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
答案 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}}