如何解决 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
上一个渲染 下一个渲染
- 使用状态使用状态
- 使用状态使用状态
- useRef useRef
- useDebugValue useDebugValue
- 使用效果使用效果
- useContext useContext
- 未定义的 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>
);
};
我在我的站点上创建了动态路由,当用户成功登录时它会发生变化。日志记录的事实我保持在全局状态,由 mobx 观察者。当用户登录成功后,路由也发生变化,并且可以正常工作,但是在控制台中,存在下一个问题: Error
文本变体错误:
react-dom.development.js:67 警告:React 检测到 AppRouter 调用的 Hooks 的顺序发生了变化。如果不修复,这将导致错误和错误。有关更多信息,请阅读挂钩规则:https://reactjs.org/link/rules-of-hooks
上一个渲染 下一个渲染
- 使用状态使用状态
- 使用状态使用状态
- useRef useRef
- useDebugValue useDebugValue
- 使用效果使用效果
- useContext useContext
- 未定义的 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>
);
};