如何解决 react-router-dom v6 和 mobx 之间的冲突?

How to solve conflict between react-router-dom v6 and mobx?

我在我的站点上创建了动态路由,当用户成功登录时它会发生变化。日志记录的事实我保持在全局状态,由 mobx 观察者。当用户登录成功后,路由也发生变化,并且可以正常工作,但是在控制台中,存在下一个问题: Error

文本变体错误:

react-dom.development.js:67 警告:React 检测到 AppRouter 调用的 Hooks 的顺序发生了变化。如果不修复,这将导致错误和错误。有关更多信息,请阅读挂钩规则:https://reactjs.org/link/rules-of-hooks

上一个渲染 下一个渲染

  1. 使用状态使用状态
  2. 使用状态使用状态
  3. useRef useRef
  4. useDebugValue useDebugValue
  5. 使用效果使用效果
  6. useContext useContext
  7. 未定义的 useContext ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^

有路由组件的截图: Routes component 路由组件代码:

import { observer } from "mobx-react-lite";
import { useContext } from "react";
import { Navigate, Route, Routes } from "react-router-dom";
import { Context } from "../..";
import { adminPaths, guestPaths, userPaths } from "./paths";
const AppRouter = () => {
  const { userStore } = useContext(Context);
  return (
    <Routes>
      <Route path='/*' element={<Navigate to='/' />} />
      {
        userStore.isAuth && userPaths.map(({ path, component }) => 
          <Route path={path} element={component()} />)
      }
      {
        userStore.isAuth && adminPaths.map(({ path, component }) => 
          <Route path={path} element={component()} />)
      }
      {
        guestPaths.map(({ path, component }) => <Route path={path} element={component()} />)
      }
    </Routes>
 )
}
export default observer(AppRouter);

当我在这个组件中删除观察者时,错误消失了,但是登录后路由没有更新。

路由配置代码: Routes configuration 路由配置代码:

import AdminCabinet from "../../pages/admin-cabinet/admin-cabinet";
import HomePage from "../../pages/home-page/home-page";
import UserCabinet from "../../pages/user-cabinet/user-cabinet";

export const guestPaths = [
    {
        name: 'Home',
        path: '/',
        component: HomePage
    }
];
export const userPaths = [
    {
        name: 'Personal cabinet',
        path: '/personalCabinet',
        component: UserCabinet
    }
];
export const adminPaths = [
    {
        name: 'Admin cabinet',
        path: '/adminCabinet',
        component: AdminCabinet
    }
];

如果有人帮助我解决这个问题,我将不胜感激。

问题

我在您的代码中看到的唯一明显问题是您直接调用您的 React 组件,而不是将它们呈现为 JSX,以便 React 处理和管理组件生命周期。

示例:

import UserCabinet from "../../pages/user-cabinet/user-cabinet";

const userPaths = [
  {
    name: "Personal cabinet",
    path: "/personalCabinet",
    component: UserCabinet,
  },
];

...

const AppRouter = () => {
  const { userStore } = useContext(Context);

  return (
    <Routes>
      ...
      {userStore.isAuth && userPaths.map(({ path, component }) => (
        <Route path={path} element={component()} /> // <-- invoking component
      ))}
      ...
    </Routes>
  );
};

解决方案

element 属性应该接收 JSX。解构时 component 将其重命名为 Component 以便它具有有效的 React 组件名称并呈现为 JSX。不要忘记为映射的路由使用有效的 React 密钥。

示例:

import UserCabinet from "../../pages/user-cabinet/user-cabinet";

const userPaths = [
  {
    name: "Personal cabinet",
    path: "/personalCabinet",
    component: UserCabinet,
  },
];

...

const AppRouter = () => {
  const { userStore } = useContext(Context);

  return (
    <Routes>
      ...
      {userStore.isAuth && userPaths.map(({ path, component: Component }) => (
        <Route
          key={path}
          path={path}
          element={<Component />} // <-- pass as JSX
        />
      ))}
      ...
    </Routes>
  );
};