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

发布于 2025-01-11 10:34:11 字数 2531 浏览 0 评论 0原文

我在网站上创建了动态路由,当用户成功登录时,动态路由会发生变化。我将日志记录保持在全局状态,由 mobx 观察。当用户登录成功后,路由也发生了变化,并且工作正常,但是在控制台中,出现了下一个问题: 错误

文本变体中的错误:

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

上一个渲染 下一个渲染

  1. useState useState
  2. useState useState
  3. useRef useRef
  4. useDebugValue useDebugValue
  5. useEffect useEffect
  6. useContext useContext
  7. undefined useContext ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^

有路线组件的屏幕截图: 路由组件 路由组件代码:

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);

当我删除此组件中的观察者时,错误消失,但路由在登录后不会更新。

路由配置代码: 路由配置 路由配置代码:

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
    }
];

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

I've created dynamic routing on my site, which changes when a user login successfully. The fact of logging I keep in global state, which observers by mobx. When the user login successfully, routes changes too, and it works correctly, but in the console, there is the next problem:
Error

Error in text variant:

react-dom.development.js:67 Warning: React has detected a change in the order of Hooks called by AppRouter. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks

Previous render Next render

  1. useState useState
  2. useState useState
  3. useRef useRef
  4. useDebugValue useDebugValue
  5. useEffect useEffect
  6. useContext useContext
  7. undefined useContext
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

There is a screenshot of the route's component:
Routes component
Routes component code:

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);

When I remove the observer in this component, error disappeared, but routes don't update after login.

Routes configuration code:
Routes configuration
Routes configuration code:

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
    }
];

I would be grateful if someone helps me with this problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

腻橙味 2025-01-18 10:34:11

问题

我在代码中看到的唯一明显的问题是,您直接调用 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>
  );
};

Issue

The only overt issue I see with your code is that you are directly invoking your React components instead of rendering them as JSX for React to handle and manage the component lifecycle of.

Example:

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>
  );
};

Solution

The element prop should receive JSX. When destructuring component rename it to Component so it has a valid React component name and render as JSX. Don't forget to use a valid React key for the mapped routes.

Example:

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>
  );
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文