Redux oidc回调叫了两次

时间:2018-05-26 12:16:39

标签: reactjs redux react-redux oidc

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; 

我的商店看起来像:

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 example

1 个答案:

答案 0 :(得分:2)

您的路由器和redux存储配置看起来很好。但您无需在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; } ,如下所示:

{{1}}