Redux oidc callback вызывается дважды - PullRequest
0 голосов
/ 26 мая 2018

Контейнер My React выглядит следующим образом:

class App extends React.Component {
  componentDidMount() {       
    if (this.props.location && this.props.location.pathname != '/callback') {      
      userManager.getUser().then(response => {        
        if (!response || response.expired) {           
          userManager.signinRedirect();
        }  
        else{
          this.props.dispatch(userFound(response));
        }
      });
    }
  }
  render() {  
    return (
      <div>
        <Switch>          
          <PrivateRoute exact path="/" component={HomePage} user={this.props.user} />
          <PrivateRoute exact path="/dashboard" component={Dashboard} user={this.props.user} />
          <Route exact path="/callback" component={CallbackPage} />
          <Route component={NotFoundPage} />          
        </Switch>
      </div>
    );
  }
}

Компонент обратного вызова выглядит следующим образом:

class CallbackPage extends React.Component {
  render() {
    // just redirect to '/' in both cases
    return (
      <CallbackComponent
        userManager={userManager}
        successCallback={() => this.props.dispatch(push("/"))}
        errorCallback={error => {
          this.props.dispatch(push("/"));
          console.error(error);
        }}
        >
        <div>Redirecting...</div>
      </CallbackComponent>
    );
  }
}

Мой Privateroute выглядит следующим образом:

const PrivateRoute = ({ component: Component, user, ...rest }) => (  
  <Route {...rest} render={props => (
    user ? (
      <Component {...props} />
    ) : (
      <Redirect to={{
        pathname: '/notFoundPage',
        state: { from: props.location }
        }}
      />
    )    
  )} />
);

export default PrivateRoute; 

Mystore выглядит так:

export default function configureStore(initialState = {}, history) {

  const middlewares = [
    sagaMiddleware,
    routerMiddleware(history),
  ];
  const enhancers = [
    applyMiddleware(...middlewares),
  ];
  const composeEnhancers =
    process.env.NODE_ENV !== 'production' &&
    typeof window === 'object' &&
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
      ? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
        // TODO Try to remove when `react-router-redux` is out of beta, LOCATION_CHANGE should not be fired more than once after hot reloading
        // Prevent recomputing reducers for `replaceReducer`
        shouldHotReload: false,
      })
      : compose;
  const store = createStore(
    createReducer(),
    fromJS(initialState),
    composeEnhancers(...enhancers)
  );
  store.runSaga = sagaMiddleware.run;
  store.injectedReducers = {}; 
  store.injectedSagas = {}; 
  loadUser(store, userManager);
  return store;
}

Моя проблема: компонент обратного вызова вызывается дважды.я не могу найти, откуда это происходит?в первый раз он переходит к функции успеха, как ожидалось, затем во второй раз он переходит к функции ошибки.Затем страница замораживается и URL-адрес в браузере является ссылкой обратного вызова.Я не могу найти, почему этот обратный вызов работает дважды?Может кто-нибудь, пожалуйста, помогите мне с этим.я надеюсь, что вы поняли проблему.

этот код основан на примере redux-oidc.Пожалуйста, нажмите на следующую ссылку. Пример Redux-OIDC

1 Ответ

0 голосов
/ 27 мая 2018

Конфигурация вашего роутера и магазина приставок выглядит нормально.Но вам не нужно звонить getUser в вашем componentWillMount.Ваше приложение должно быть настроено таким образом, чтобы оно отображало маршруты только при наличии действительного пользователя.

Возможное решение - использовать render вместо componentWillMount, например:

render() {
  const routes = (
    <Switch>          
      <Route exact path="/" component={HomePage} user={this.props.user} />
      <Route exact path="/dashboard" component={Dashboard} user={this.props.user} />
      <Route exact path="/callback" component={CallbackPage} />
      <Route component={NotFoundPage} />          
    </Switch>
  );

  const loginPage = <LoginPage />; // <-- create a dedicated login page component where signinRedirect is called

  const isValidUserPresent = this.props.user && !this.props.user.expired;
  const isCallbackRouteRequested = this.props.location.pathname === '/callback';
  const shouldRenderRoutes = isValidUserPresent || isCallbackRouteRequested;

  return shouldRenderRoutes ? routes : loginPage;            
}
...