You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Router<Redirect>刷新时localStorage存用户仍不跳转如何解决

问题根因

  1. React的useEffect回调会在组件首次渲染完成后才执行,你的组件首次渲染时user初始值为null,如果此时访问根路径/,会直接触发重定向到/login。等useEffect读取localStorage更新user为已登录状态时,页面已经停留在/login路径,根路径下的三元判断逻辑不会再执行,自然不会自动跳转到/dashboard。
  2. 现有/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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 14:06:04