React Router<Redirect>刷新时localStorage存用户仍不跳转如何解决
问题根因
- React的
useEffect回调会在组件首次渲染完成后才执行,你的组件首次渲染时user初始值为null,如果此时访问根路径/,会直接触发重定向到/login。等useEffect读取localStorage更新user为已登录状态时,页面已经停留在/login路径,根路径下的三元判断逻辑不会再执行,自然不会自动跳转到/dashboard。 - 现有
/login、/dashboard路由没有做权限校验,已登录用户可正常访问登录页,未登录用户也可以直接访问仪表盘路径,不符合业务预期。
解决方案
建议新增加载状态避免未读取完用户状态就提前触发重定向,同时封装路由守卫统一处理访问权限,修改后代码如下:
// 私有路由组件:仅登录用户可访问,未登录自动跳转登录页 const PrivateRoute = ({ children, user, ...rest }) => { return ( <Route {...rest} render={({ location }) => user ? ( children ) : ( <Redirect to={{ pathname: "/login", state: { from: location } }} /> ) } /> ); }; // 公开路由组件:仅未登录用户可访问,已登录自动跳转仪表盘 const PublicRoute = ({ children, user, ...rest }) => { return ( <Route {...rest} render={({ location }) => !user ? ( children ) : ( <Redirect to={{ pathname: "/dashboard", state: { from: location } }} /> ) } /> ); }; const App = () => { const [user, setUser] = useState(null) // 新增加载状态,等待用户状态读取完成后再渲染路由 const [loading, setLoading] = useState(true) useEffect(() => { const loggedUserJSON = window.localStorage.getItem('loggedUser') if (loggedUserJSON) { const user = JSON.parse(loggedUserJSON) setUser(user) noteService.setToken(user.token) } setLoading(false) }, []) // 加载阶段返回占位内容,避免提前渲染路由触发错误重定向 if(loading) return <div>加载中...</div> return ( <Router> <Switch> <PublicRoute exact path='/login' user={user}> <LogIn /> </PublicRoute> <PrivateRoute exact path='/dashboard' user={user}> <Dashboard /> </PrivateRoute> <Route exact path='/'> <Redirect to={user ? '/dashboard' : '/login'} /> </Route> </Switch> </Router> ) }
修改后不仅可以解决刷新后不跳转仪表盘的问题,还可以避免已登录用户手动访问登录页、未登录用户手动访问仪表盘的异常场景。
内容的提问来源于stack exchange,提问作者Htet Oo Wai Yan
相关产品推荐
相关产品推荐

