刷新页面导致页面呈现空白并抛出navigate()错误

问题描述 投票:0回答:1

我用 Astro、React 和 RRDv6 构建了这个简单的混合 SPA
路由树:

˫ localhost/ ------------------(公共页面)
˫ localhost/login ------------(管理员登录页面)
˪ localhost/admin/home ---(管理仪表板页面)

当我成功登录并重定向到管理仪表板页面时,没有错误或任何警告出现。我尝试刷新页面来模拟刷新仪表板以通过API从数据库中获取最新数据。相反,我的控制台日志中出现此错误,并且我的页面呈现为空白。

未捕获错误:

useNavigate()
只能在以下情况下使用:
<Router>
组件。

我是否错过了 RRDv6 概念,或者错过了一些重要的东西?

env: node 16.13.0, npm 8.3.0
deps: @astrojs/react 2.0.2, astro 2.0.16, react 18.2.0, react-router-dom 6.11.1
script: dev = astro dev
cmd: npm run dev

路线:

export default function Admin() {
  const [cookie, setCookie, removeCookie] = useCookies(['token']);

  const PrivateRoute = () => {
    const location = useLocation()

    const isAuthenticated = () => {
      return cookie.token !== null && cookie.token !== undefined;
    };

    return isAuthenticated()
      ? <Outlet />
      : <Navigate to="/admin" replace state={{ from: location }} />;
  };

  return (
    <BrowserRouter>
      <Routes>
        <Route path="/login" element={<AdminLogin />} />
        <Route path="/admin" element={<PrivateRoute />}>
          <Route path="home" element={<AdminHome />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

管理仪表板:

export default function AdminHome() {
  const [cookie, setCookie, removeCookie] = useCookies(['token']);
  const [doLogout, setDoLogout] = useState(false)

  const navigate= useNavigate()

  useEffect(() => {
    if (doLogout) {
      removeCookie('token', { sameSite: 'none', secure: true })
      navigate('/login')
    }
  }, [doLogout])

  return (
    <div>
      <AdminAppbar cookie={cookie} logout={setDoLogout} />
      <AdminBlog/>
    </div>
  );
}
javascript reactjs react-router react-router-dom astrojs
1个回答
0
投票

我在代码中看到的唯一问题是:

  • PrivateRoute
    组件在另一个 React 组件中声明。每次父组件渲染时,都会创建
    PrivateRoute
    的新“实例”,并且 that 组件的整个 ReactTree 会被拆除并安装新的“实例”。 React 组件通常应该单独声明。

  • isAuthenticated

    评估为 false 时,

    受保护的路由将重定向到自身。这可能会创建渲染循环,这就是页面为空白的原因。您正在保护的路由不应重定向到其他受保护的路由。

    更新

    PrivateRoute
    以重定向到身份验证路由。

const PrivateRoute = () => {
  const location = useLocation();
  const [cookie, setCookie, removeCookie] = useCookies(['token']);

  const isAuthenticated = cookie.token !== null && cookie.token !== undefined;

  return isAuthenticated
    ? <Outlet />
    : (
      <Navigate
        to="/login" // <-- redirect to non-protected route
        replace
        state={{ from: location }}
      />
    );
};
export default function Admin() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/login" element={<AdminLogin />} />
        <Route path="/admin" element={<PrivateRoute />}>
          <Route path="home" element={<AdminHome />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}
© www.soinside.com 2019 - 2024. All rights reserved.