React.js PrivateRoute刷新页面时isAuthenticated初始为false跳转问题
问题原因
- Redux中
isAuthenticated的初始值默认为false,应用初始化时还未执行身份校验逻辑,该状态不代表真实的登录情况。 - 手动输入私有路由地址时,路由组件渲染优先级高于异步身份校验请求的响应速度:首次渲染PrivateRoute时,校验登录态的refresh、check_Authenticated请求还未返回,直接读取到初始的false值触发重定向,后续即使
isAuthenticated更新为true,页面已经跳转到登录页,不会再触发私有路由的逻辑。 - 路由逻辑中没有加入「身份校验中」的加载状态判断,直接基于未确认的初始状态执行了重定向。
另外你原有代码中connect的第二个参数传入{PrivateRoute}/{PublicRoute}属于冗余配置,没有实际作用,后续可以直接删除。
解决方案
- 第一步:给auth状态新增
authLoading字段,标记身份校验的执行状态
初始值设为true,身份校验请求(不管成功还是失败)完成后更新为false,示例reducer逻辑:
const initialState = { isAuthenticated: false, authLoading: true, user: null } // 校验完成的action处理逻辑示例 case 'CHECK_AUTH_COMPLETE': return { ...state, isAuthenticated: payload.isAuthenticated, authLoading: false }
- 第二步:修改PrivateRoute逻辑,加入加载状态判断,校验未完成时不执行重定向,先渲染加载占位
改后的PrivateRoute代码:
const PrivateRoute = ({component: Component, isAuthenticated, authLoading, ...rest}) => { return ( <Route {...rest} render={props => { // 校验未完成时渲染加载状态,不执行跳转 if (authLoading) return <div>加载中...</div> return isAuthenticated ? <Component {...props} /> : <Redirect to="/login"/> }}/> ); }; const mapStateToProps = state => ({ isAuthenticated: state.auth.isAuthenticated, authLoading: state.auth.authLoading }); export default connect(mapStateToProps)(PrivateRoute);
同时对应修改PublicRoute,避免公共路由在校验未完成时错误跳转:
const PublicRoute = ({component: Component, isAuthenticated, restricted, authLoading, ...rest}) => { return ( <Route {...rest} render={props => { if (authLoading) return <div>加载中...</div> return isAuthenticated && restricted ? <Redirect to="/browser"/> : <Component {...props} /> }}/> ); }; const mapStateToProps = state => ({ isAuthenticated: state.auth.isAuthenticated, authLoading: state.auth.authLoading }); export default connect(mapStateToProps)(PublicRoute);
- 第三步:确保应用初始化时优先触发身份校验逻辑,可在App组件挂载时执行校验请求,保证校验流程在路由判断前启动。
内容的提问来源于stack exchange,提问作者Nima
相关产品推荐
相关产品推荐

