当前位置: 首页 > 知识库问答 >
问题:

前端 - react-router-dom v6 如何根据数据动态渲染路由?

巫马浩言
2024-09-10

const routes = [
{

path: "/",
element: <App />,
loader: authLoader,
children: [
  {
    errorElement: <ErrorPage />,
    children: [
      {
        index: true,
        title: "系统概况",
        icon: <DashboardOutlined />,
        element: <Dashboard />,
      },
      {
        path: "stations/-7",
        title: "运维管理",
        icon: <ConsoleSqlOutlined />,
        element: <Operation />,
        children: [
          {
            path: "/stations/-7",
            title: "巡检记录",
            element: <AccountCenter />,
          },
        ],
      },
      {
        path: "stations/0",
        title: "运维管理",
        icon: <ConsoleSqlOutlined />,
        element: <Operation />,
      },
      {
        path: "form",
        title: "表单页",
        icon: <EditOutlined />,
        element: <FormPage />,
      },
      {
        path: "table",
        title: "列表页",
        icon: <TableOutlined />,
        element: <TablePage />,
      },
      {
        path: "detail",
        title: "详情页",
        icon: <BarsOutlined />,
        element: <DetailPage />,
      },
      {
        path: "account",
        title: "个人页",
        icon: <UserOutlined />,
        children: [
          {
            path: "/account/center",
            title: "个人中心",
            element: <AccountCenter />,
          },
          {
            path: "/account/settings",
            title: "个人设置",
            element: <AccountSettings />,
          },
        ],
      },
      // {
      //   path: "*",
      //   element: <Navigate to="/" replace={true} />,
      // },
    ],
  },
],

},
{

path: "/login",
element: <LoginPage />,

},
];
// console.log(routes);

export { routes };

export default createBrowserRouter(routes);
这是我的路由表,现在是静态写的,如何根据后端返回的数据动态渲染路由表?在这里面不能使用hook, 我在别的组件可以这样获取到数据
import { useMenuStore } from "@stores/index";
const { menuInfo } = useMenuStore();

在路由表里面写过函数,使用hook获取数据,报错

警告:钩子调用无效。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一:
1.你可能有不匹配的React版本和渲染器(如React DOM)
2.你可能违反了钩子规则
3.同一个应用程序中可能有多个React副本

有没有其他的解决方案,能动态渲染就行,数据如下,树形结构的rows:[

{
    "mid": null,
    "name": null,
    "link": null,
    "path": "/stations/0",
    "order": 999,
    "parent": null,
    "valid": null,
    "mark": null,
    "icon": "ant-design",
    "style": null,
    "id": 1,
    "parentId": 0,
    "key": "module_1",
    "parentKey": null,
    "text": "环境数据",
    "children": [
        {
            "mid": null,
            "name": null,
            "link": null,
            "path": "/stations/0",
            "order": 999,
            "parent": null,
            "valid": null,
            "mark": null,
            "icon": "align-left",
            "style": null,
            "id": 4,
            "parentId": 1,
            "key": "module_4",
            "parentKey": "module_1",
            "text": "数据管理",
            "children": [
                {
                    "mid": null,
                    "name": null,
                    "link": null,
                    "path": "/stations/0",
                    "order": 992,
                    "parent": null,
                    "valid": null,
                    "mark": null,
                    "icon": "book",
                    "style": null,
                    "id": 11,
                    "parentId": 4,
                    "key": "module_11",
                    "parentKey": "module_4",
                    "text": "实时数据",
                    "children": []
                },

共有1个答案

乐修远
2024-09-10

在React Router v6中,由于路由配置通常在组件外部定义(例如,在模块级别或应用启动时),因此直接使用Hooks(如useStateuseEffect)来获取数据并动态构建路由是不可行的,因为Hooks只能在函数组件内部使用。

为了解决这个问题,你可以采取以下策略之一:

1. 使用React Context或Redux来传递路由配置

由于你已经在使用状态管理(如useMenuStore),你可以考虑在应用的顶层组件中(如App组件)使用useMenuStore来获取路由数据,并在组件树中通过Context或Redux将这些数据传递给负责创建路由配置的组件。

步骤:

  1. 在顶层组件中获取数据
    App组件或其他顶层组件中,使用useMenuStore获取路由数据。
  2. 使用Context或Redux传递数据
    将路由数据通过Context或Redux传递给需要它的组件。
  3. 动态构建路由
    在接收到路由数据的组件中,根据这些数据动态构建路由配置,并使用createBrowserRouter创建路由。

2. 在组件加载时动态构建路由

如果路由数据在应用启动时不是立即可用的,你可以在应用的某个加载阶段(如App组件的useEffect中)获取数据,并更新路由配置。然而,这种方法可能需要你更新整个路由配置,或者找到一种方法来动态地添加/删除路由。

示例代码(使用Context传递路由数据):

// 假设你有一个Context来传递路由数据
const RouterDataContext = React.createContext(null);

// 顶层组件
function App() {
  const { menuInfo } = useMenuStore();
  const routes = useMemo(() => {
    // 根据menuInfo动态构建路由
    // ...
    return [...]; // 返回构建好的路由数组
  }, [menuInfo]);

  return (
    <RouterDataContext.Provider value={routes}>
      <RouterProvider router={createBrowserRouter(routes)} />
      {/* 其他组件 */}
    </RouterDataContext.Provider>
  );
}

// 组件内部使用Context获取路由数据(如果需要)
function SomeComponent() {
  const routes = useContext(RouterDataContext);
  // 使用routes或进行其他操作
  return <div>...</div>;
}

注意:在实际应用中,你可能不需要在组件内部直接使用RouterDataContext,这取决于你的应用结构和需求。通常,路由配置只需要在应用启动时构建一次,并传递给RouterProvider

3. 注意事项

  • 确保在应用加载和渲染路由之前,路由数据是可用的。
  • 考虑到SEO和初始加载时间,如果路由数据来自外部源(如API),请确保该过程足够快,或者提供适当的加载指示器。
  • 如果路由数据发生变化,并且需要更新路由配置,请考虑重新渲染相关组件或整个应用,以反映这些更改。在React Router v6中,这通常意味着更新传递给RouterProviderrouter属性。然而,这通常不是推荐的做法,因为它可能导致不必要的重新渲染和性能问题。更好的做法是在应用启动时构建一次路由配置,并在后续的数据更新中通过其他方式(如页面跳转或导航)来反映这些更改。
 类似资料:
  • 根据数据库里面获取到的数据信息渲染表格,起初根据数据结构生成了四列,但是由于后续数据库里面会有数据结构上的变化,会增加字段,那我要如何在表格中去追加这部分新数据,从而在前端渲染出一个新的表格————就是说原来四列变六列,并把对应数据也一同渲染上去。

  • 问题内容: 在React JSX中,似乎无法执行以下操作: 我收到一个解析错误:意外令牌{。这不是React可以处理的吗? 我正在设计此组件,以便在内部隐藏的值将包含有效的HTML元素(h1,p等)。有什么办法可以使这项工作吗? 问题答案: 您不应该将组件子弹放在花括号中: 这是一个有效的小提琴:http : //jsfiddle.net/kb3gN/6668/ 此外,您还可以找到JSX编译器,有

  • 本文向大家介绍ListView实现下拉动态渲染数据,包括了ListView实现下拉动态渲染数据的使用技巧和注意事项,需要的朋友参考一下 这是一篇关于LIstView实现动态数据渲染的文章!  首先我们讲讲数据是如何来规划的 一般情况下我们有两种规划方案 前提比如我们数据是100条+ 第一:一次性把100条数据fetch过来 然后由前端JS代码来做分页处理(如每次渲染10条) 第二:在server端

  • 请问这样的数据在el-table里如何渲染出来,activityList也要渲染 id activityList 1 test1(2),test2(3) 这样的数据应该如何去渲染 还是处理一下rows里面的activityList这个数据?

  • 问题内容: 我试图将我的一些路由与React Router v4一起分组以清理一些组件。现在,我只想将非登录路由组和管理路由分组在一起,但是以下操作无效。 main.js public.js Greeting组件显示在“ localhost:3000 /”,但SignupPage组件显示在“ localhost:3000 / signup”,而Login组件不显示在“ localhost:3000

  • 我对如何从根开始做(多个)可选路径参数有点困惑。我用的是React-Router3和Redux4.3。 据我所知,应该可以工作,但在加载应用程序时,我遇到了以下错误: