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

React状态路由重定向问题:更新isInstalled后未跳转至/login

问题描述

我通过调用后端API检查CMS是否已安装,能获取返回值且控制台显示“ok”,但未按预期重定向至/login页面。我怀疑const content = useRoutes(routes(isInstalled, isLogged));未更新,isInstalled状态更新后,新值没有传递给routes.js。

App.js代码:

function App() {
  const [isLogged, setIsLogged] = useState<boolean>(false);
  const [isInstalled, setIsInstalled] = useState<boolean>(false);
  const [client, setClient] = useState<any>();
  const content = useRoutes(routes(isInstalled, isLogged));
  const location = useLocation();

  useEffect(() => {
    const transport = createGrpcWebTransport({
      baseUrl: `http://127.0.0.1:50051`,
    });
    const client = createPromiseClient(Lucle, transport);
    setClient(client);

    if (location.pathname == "/admin") {
      check_if_installed(client)
        .then(() => {
         console.log("ok");
         setIsInstalled(true)
         })
        .catch(() => {
          console.log("NOK");
          setIsInstalled(false)
        });
    }
  }, []);

  return (
    <StyledEngineProvider injectFirst>
      <ThemeProvider theme={theme}>
        <GlobalStyles />
        {content}
      </ThemeProvider>
    </StyledEngineProvider>
  );
}

routes.js代码:

const routes = (isInstalled: boolean, isLogged: boolean) => [
  { path: "/login", element: <Login /> },
  {
    path: "admin",
    element: !isInstalled ? (
      <Navigate to="/install" />
    ) : !isLogged ? (
      <Navigate to="/login" />
    ) : (
      <Dashboard />
    ),
    children: [
      { path: "", element: <AdminIndex /> },
      { path: "editor", element: <OnlineEditor /> },
      { path: "tables", element: <Tables /> },
    ],
  },
  {
    path: "/install",
    element: <Install />,
  },
];

修复方案

1. 修正路由路径匹配错误

routes.js中admin路由的path设置为相对路径"admin",但实际访问的是绝对路径/admin,导致路由无法匹配,跳转逻辑不触发。

修改routes.js:

const routes = (isInstalled: boolean, isLogged: boolean) => [
  { path: "/login", element: <Login /> },
  {
    path: "/admin", // 改为绝对路径,匹配实际访问路径
    element: !isInstalled ? (
      <Navigate to="/install" replace />
    ) : !isLogged ? (
      <Navigate to="/login" replace /> // 添加replace避免历史记录冗余
    ) : (
      <Dashboard />
    ),
    children: [
      { path: "", element: <AdminIndex /> },
      { path: "editor", element: <OnlineEditor /> },
      { path: "tables", element: <Tables /> },
    ],
  },
  {
    path: "/install",
    element: <Install />,
  },
];

2. 补充useEffect依赖,确保状态检查逻辑实时触发

原useEffect依赖数组为空,仅在组件挂载时执行一次。如果初始加载路径不是/admin,后续导航到该路径时不会重新调用安装检查接口。

修改App.js的useEffect:

useEffect(() => {
  const transport = createGrpcWebTransport({
    baseUrl: `http://127.0.0.1:50051`,
  });
  const client = createPromiseClient(Lucle, transport);
  setClient(client);

  if (location.pathname === "/admin") {
    check_if_installed(client)
      .then(() => {
        console.log("ok");
        setIsInstalled(true);
      })
      .catch(() => {
        console.log("NOK");
        setIsInstalled(false);
      });
  }
}, [location]); // 添加location依赖,路径变化时重新执行检查

3. 状态更新后的路由自动生效

当isInstalled或isLogged状态变化时,组件会重新渲染,routes(isInstalled, isLogged)会生成新的路由配置数组,useRoutes会自动根据新配置更新路由内容,无需额外操作。

内容的提问来源于stack exchange,提问作者Vana

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 18:46:12