如何将API中的路径映射到React Router?

huangapple go评论72阅读模式
英文:

How can I map path from API into the React Router?

问题

I am planning to map the path that I got from the API. It will be set into the routeList. Then I want to map into one of the children for my /app route.

const [routeList, setRouteList] = useState([]);
useEffect(() => {
  Promise.all([
    axios.get("http://localhost:5000/rights"),
    axios.get("http://localhost:5000/children")
  ])
    .then((res) => {
      setRouteList([...res[0].data, ...res[1].data]);
    });
}, []);
const element = useRoutes([
  {
    path: "/login",
    element: LazyLoad("login/Login"),
  },
  {
    path: "/app",
    element: <AuthComponent> 
    {LazyLoad("sandbox/Sandbox")}</AuthComponent>,
    children: [
      {
        path: "",
        element: <Redirect to="/app/home" />,
      },
      routeList.map((item) => {
        `path: ${item.key}, element: 
  ${LocalRouterMapping[item.key]}`;
      }),
      {
        path: "*",
        element: 
  LazyLoad("noPermission/NoPermission"),
      },
    ],
  },
]);

But I get an error for doing this

routeList.map((item) => {
  `path: ${item.key}, element: ${LocalRouterMapping[item.key]}`;
}),

The error from the command prompt is Line 40:11: Expected an assignment or function call and instead saw an expression no-unused-expressions.

I tried to change the format but still not working.

I have another issue my element needed to be wrapped in LazyLoad function to use React.Suspense. May I know how can I do it?

const LazyLoad = (path) => {
  const Comp = React.lazy(() => 
    import(`../views/${path}`));
    return (
      <React.Suspense fallback={<Loading...>}>
        <Comp />
      </React.Suspense>
    );
};

And here is how I do it but the path with the element is not created. I will just always redirect to the path: "*".

routeList.map((item) => ({
  path: item.key,
  element: LazyLoad(`${LocalRouterMapping[item.key]}`),
})),

Here's my LocalRouterMapping:

const LocalRouterMapping = {
  "/home": "dashboard/Dashboard",
  "/user-manage/list": "user-manage/UserList",
  "/access-manage/access/list": "access-manage/AccessList",
  "/access-manage/role/list": "access-manage/RoleList",
  "/news-manage/add": "inventory/CreateInventory",
  "/news-manage/draft": "inventory/InventoryDraft",
  "/news-manage/category": "inventory/InventoryCategory",
  "/audit-manage/audit": "audit/AuditInventory",
  "/audit-manage/list": "audit/AuditList",
};

These are the data from axios datafromAxios.

Here's my whole code:

import React, { useEffect, useState } from "react";
import { useRoutes } from "react-router-dom";
import Redirect from "../components/Redirect";
import axios from "axios";

const LocalRouterMapping = {
  "/home": "dashboard/Dashboard",
  "/user-manage/list": "user-manage/UserList",
  "/access-manage/access/list": "access-manage/AccessList",
  "/access-manage/role/list": "access-manage/RoleList",
  "/news-manage/add": "inventory/CreateInventory",
  "/news-manage/draft": "inventory/InventoryDraft",
  "/news-manage/category": "inventory/InventoryCategory",
  "/audit-manage/audit": "audit/AuditInventory",
  "/audit-manage/list": "audit/AuditList",
};
export default function IndexRouter() {
  const [routeList, setRouteList] = useState([]);
  useEffect(() => {
    Promise.all([axios.get("http://localhost:5000/rights"), axios.get("http://localhost:5000/children")]).then((res) => {
      const combinedRoutes = [...res[0].data, ...res[1].data];
      setRouteList(combinedRoutes.filter((item) => LocalRouterMapping[item.key]));
    });
  }, []);
  const element = useRoutes([
    {
      path: "/login",
      element: LazyLoad("login/Login"),
    },
    {
      path: "/app",
      element: <AuthComponent> {LazyLoad("sandbox/Sandbox")} </AuthComponent>,
      children: [
        {
          path: "",
          element: <Redirect to="/app/home" />,
        },
        routeList.map((item) => ({
          path: item.key.slice(1),
          element: <AuthComponent>{LazyLoad(LocalRouterMapping[item.key])}</AuthComponent>,
        })),
        {
          path: "*",
          element: LazyLoad("noPermission/NoPermission"),
        },
      ],
    },
    {
      path: "/dashboard",
      element: <AuthComponent>{LazyLoad("dashboard/Dashboard")}</AuthComponent>,
    },
    {
      path: "/product",
      element: <AuthComponent> 
     {LazyLoad("dashboard/Dashboard")} 
     </AuthComponent>,
    },
    {
      path: "/",
      element: <Redirect to="/app" />,
    },
    {
      path: "*",
      element: LazyLoad("notFound/NotFound"),
    },
  ]);
  return element;
}

function AuthComponent({ children }) {
  const isLogin = localStorage.getItem("token");
  return isLogin ? children : <Redirect to="/login" />;
}

const LazyLoad = (path) => {
  const Comp = React.lazy(() => import(`../views/${path}`));
  return (
    <React.Suspense fallback={<Loading...>}>
      <Comp />
    </React.Suspense>
  );
};
英文:

I am planning to map the path that I got from the API. It will be set into the routeList. Then I want to map into one of the children for my &quot;/app&quot; route.

const [routeList, setRouteList] = useState([]);
useEffect(() =&gt; {
  Promise.all([
    axios.get(&quot;http://localhost:5000/rights&quot;),
    axios.get(&quot;http://localhost:5000/children&quot;)
  ])
    .then((res) =&gt; {
      setRouteList([...res[0].data, ...res[1].data]);
    });
}, []);
const element = useRoutes([
  {
    path: &quot;/login&quot;,
    element: LazyLoad(&quot;login/Login&quot;),
  },
  {
    path: &quot;/app&quot;,
    element: &lt;AuthComponent&gt; 
   {LazyLoad(&quot;sandbox/Sandbox&quot;)}&lt;/AuthComponent&gt;,
      children: [
        {
          path: &quot;&quot;,
          element: &lt;Redirect to=&quot;/app/home&quot; /&gt;,
        },
        routeList.map((item) =&gt; {
          `path: ${item.key}, element: 
${LocalRouterMapping[item.key]}`;
        }),
        {
          path: &quot;*&quot;,
          element: 
    LazyLoad(&quot;noPermission/NoPermission&quot;),
          },
        ],
     },
    ]);

But I get an error for doing this

routeList.map((item) =&gt; {
  `path: ${item.key}, element: ${LocalRouterMapping[item.key]}`;
}),

The error from the command prompt is Line 40:11: Expected an assignment or function call and instead saw an expression no-unused-expressions.

I tried to change the format but still not working.

I have another issue my element needed to be wrapped in LazyLoad function to use React.Suspence. May I know how can I do it?

const LazyLoad = (path) =&gt; {
const Comp = React.lazy(() =&gt; 
import(`../views/${path}`));
return (
&lt;React.Suspense fallback={&lt;&gt;Loading...&lt;/&gt;}&gt;
&lt;Comp /&gt;
&lt;/React.Suspense&gt;
);
};

And here is how I do it but the path with the element is not created. I will just always redirect to the path: "*"

      routeList.map((item) =&gt; ({
path: item.key,
element: LazyLoad(`${LocalRouterMapping[item.key]}`),
})),

Here's my LocalRouterMapping

const LocalRouterMapping = {
&quot;/home&quot;: &quot;dashboard/Dashboard&quot;,
&quot;/user-manage/list&quot;: &quot;user-manage/UserList&quot;,
&quot;/access-manage/access/list&quot;: &quot;access-manage/AccessList&quot;,
&quot;/access-manage/role/list&quot;: &quot;access-manage/RoleList&quot;,
&quot;/news-manage/add&quot;: &quot;inventory/CreateInventory&quot;,
&quot;/news-manage/draft&quot;: &quot;inventory/InventoryDraft&quot;,
&quot;/news-manage/category&quot;: &quot;inventory/InventoryCategory&quot;,
&quot;/audit-manage/audit&quot;: &quot;audit/AuditInventory&quot;,
&quot;/audit-manage/list&quot;: &quot;audit/AuditList&quot;,
};

These are the data from axios 如何将API中的路径映射到React Router?

Here's my whole code

import React, { useEffect, useState } from &quot;react&quot;;
import { useRoutes } from &quot;react-router-dom&quot;;
import Redirect from &quot;../components/Redirect&quot;;
import axios from &quot;axios&quot;;
const LocalRouterMapping = {
&quot;/home&quot;: &quot;dashboard/Dashboard&quot;,
&quot;/user-manage/list&quot;: &quot;user-manage/UserList&quot;,
&quot;/access-manage/access/list&quot;: &quot;access-manage/AccessList&quot;,
&quot;/access-manage/role/list&quot;: &quot;access-manage/RoleList&quot;,
&quot;/news-manage/add&quot;: &quot;inventory/CreateInventory&quot;,
&quot;/news-manage/draft&quot;: &quot;inventory/InventoryDraft&quot;,
&quot;/news-manage/category&quot;: &quot;inventory/InventoryCategory&quot;,
&quot;/audit-manage/audit&quot;: &quot;audit/AuditInventory&quot;,
&quot;/audit-manage/list&quot;: &quot;audit/AuditList&quot;,};
export default function IndexRouter() {
const [routeList, setRouteList] = useState([]);
useEffect(() =&gt; {Promise.all([axios.get(&quot;http://localhost:5000/rights&quot;), axios.get(&quot;http://localhost:5000/children&quot;)]).then((res) =&gt; {
const combinedRoutes = [...res[0].data, ...res[1].data];
setRouteList(combinedRoutes.filter((item) =&gt; LocalRouterMapping[item.key]));
});
}, []);
const element = useRoutes([
{
path: &quot;/login&quot;,
element: LazyLoad(&quot;login/Login&quot;),
},
{
path: &quot;/app&quot;,
element: &lt;AuthComponent&gt; {LazyLoad(&quot;sandbox/Sandbox&quot;)} &lt;/AuthComponent&gt;,
children: [
{
path: &quot;&quot;,
element: &lt;Redirect to=&quot;/app/home&quot; /&gt;,
},
routeList.map((item) =&gt; ({
path: item.key.slice(1),
element: &lt;AuthComponent&gt;{LazyLoad(LocalRouterMapping[item.key])}&lt;/AuthComponent&gt;,
})),
{
path: &quot;*&quot;,
element: LazyLoad(&quot;noPermission/NoPermission&quot;),
},
],
},
{
path: &quot;/dashboard&quot;,
element: &lt;AuthComponent&gt;{LazyLoad(&quot;dashboard/Dashboard&quot;)}&lt;/AuthComponent&gt;,
},
{
path: &quot;/product&quot;,
element: &lt;AuthComponent&gt; 
{LazyLoad(&quot;dashboard/Dashboard&quot;)} 
&lt;/AuthComponent&gt;,
},
{
path: &quot;/&quot;,
element: &lt;Redirect to=&quot;/app&quot; /&gt;,
},
{
path: &quot;*&quot;,
element: LazyLoad(&quot;notFound/NotFound&quot;),
},
]);
return element;
}
function AuthComponent({ children }) {
const isLogin = localStorage.getItem(&quot;token&quot;);
return isLogin ? children : &lt;Redirect to=&quot;/login&quot; /&gt;;
}
const LazyLoad = (path) =&gt; {
const Comp = React.lazy(() =&gt; import(`../views/${path}`));
return (
&lt;React.Suspense fallback={&lt;&gt;Loading...&lt;/&gt;}&gt;
&lt;Comp /&gt;
&lt;/React.Suspense&gt;
);
};

答案1

得分: 0

你使用字符串模板映射到一个字符串值,但却没有返回映射后的值。你应该映射到一个 RouteObject 对象。

示例:

routeList.map(({ key }) => ({
  path: key,
  element: LazyLoad(LocalRouterMapping[key]),
})),

完整的代码:

const element = useRoutes([
  {
    path: "/login",
    element: LazyLoad("login/Login"),
  },
  {
    path: "/app",
    element: <AuthComponent>{LazyLoad("sandbox/Sandbox")}</AuthComponent>,
    children: [
      {
        index: true,
        element: <Redirect to="/app/home" />,
      },
      routeList
        // 确保存在组件映射
        .filter(item => LocalRouterMapping[item.key])
        // 映射到 RouteObject 属性
        .map((item) => ({
          path: item.key,
          element: LazyLoad(LocalRouterMapping[item.key]),
        })),
      {
        path: "*",
        element: LazyLoad("noPermission/NoPermission"),
      },
    ],
  },
]);
英文:

You are mapping to a string value using string templating, but then also fail to return a mapped value. You should map to a RouteObject object instead.

Example:

routeList.map(({ key }) =&gt; ({
  path: key,
  element: LazyLoad(LocalRouterMapping[key]),
})),

Complete code:

const element = useRoutes([
  {
    path: &quot;/login&quot;,
    element: LazyLoad(&quot;login/Login&quot;),
  },
  {
    path: &quot;/app&quot;,
    element: &lt;AuthComponent&gt;{LazyLoad(&quot;sandbox/Sandbox&quot;)}&lt;/AuthComponent&gt;,
    children: [
      {
        index: true,
        element: &lt;Redirect to=&quot;/app/home&quot; /&gt;,
      },
      routeList
        // Ensure there is component mapping
        .filter(item =&gt; LocalRouterMapping[item.key])
        // Map to RouteObject properties
        .map((item) =&gt; ({
          path: item.key,
          element: LazyLoad(LocalRouterMapping[item.key]),
        })),
      {
        path: &quot;*&quot;,
        element: LazyLoad(&quot;noPermission/NoPermission&quot;),
      },
    ],
  },
]);

答案2

得分: 0

我通过使用Route组件而不是使用useRoute来找到了解决方案。以下是使用相同映射样式的源代码:

const LocalRouterMapping = {
  "/home": "dashboard/Dashboard",
  "/user-manage/list": "user-manage/UserList",
  "/access-manage/access/list": "access-manage/AccessList",
  "/access-manage/role/list": "access-manage/RoleList",
  "/inventory-manage/add": "inventory/CreateInventory",
  "/inventory-manage/list": "inventory/InventoryList",
  "/inventory-manage/preview/:id": "inventory/InventoryDetails",
  "/inventory-manage/update/:id": "inventory/InventoryUpdate",
  "/inventory-manage/category": "inventory/InventoryCategory",
};

<Routes>
  <Route path="/login" element={LazyLoad("login/Login")} />
  <Route path="/app" element={LazyLoad("sandbox/Sandbox")}>
    <Route path="" element={<Navigate to="home" />} />
    <Route path="*" element={<AuthComponent>{LazyLoad("noPermission/NoPermission")}</AuthComponent>} />
    {routeList.map((item) => {
      if (checkPagePermission(item) && checkUserPermission(item)) {
        return (
          <Route
            path={item.key.slice(1)}
            key={item.key.slice(1)}
            element={<AuthComponent>{LazyLoad(LocalRouterMapping[item.key])}</AuthComponent>}
          />
        );
      }
      return <Route path="*" key={item.key.slice(1)} element={<AuthComponent>{LazyLoad("noPermission/NoPermission")}</AuthComponent>} />;
    })}
  </Route>
  <Route path="/" element={<Navigate to="/app" />} />
  <Route path="*" element={LazyLoad("notFound/NotFound")} />
</Routes>
英文:

I found the solution by using Route component instead of using the useRoute.

Here's my source code using the same mapping style.

const LocalRouterMapping = {
&quot;/home&quot;: &quot;dashboard/Dashboard&quot;,
&quot;/user-manage/list&quot;: &quot;user-manage/UserList&quot;,
&quot;/access-manage/access/list&quot;: &quot;access-manage/AccessList&quot;,
&quot;/access-manage/role/list&quot;: &quot;access-manage/RoleList&quot;,
&quot;/inventory-manage/add&quot;: &quot;inventory/CreateInventory&quot;,
&quot;/inventory-manage/list&quot;: &quot;inventory/InventoryList&quot;,
&quot;/inventory-manage/preview/:id&quot;: &quot;inventory/InventoryDetails&quot;,
&quot;/inventory-manage/update/:id&quot;: &quot;inventory/InventoryUpdate&quot;,
&quot;/inventory-manage/category&quot;: &quot;inventory/InventoryCategory&quot;,
};
&lt;Routes&gt;
&lt;Route path=&quot;/login&quot; element={LazyLoad(&quot;login/Login&quot;)} /&gt;
&lt;Route path=&quot;/app&quot; element={LazyLoad(&quot;sandbox/Sandbox&quot;)}&gt;
&lt;Route path=&quot;&quot; element={&lt;Navigate to={&quot;home&quot;} /&gt;} /&gt;
&lt;Route path=&quot;*&quot; element={&lt;AuthComponent&gt;{LazyLoad(&quot;noPermission/NoPermission&quot;)}&lt;/AuthComponent&gt;} /&gt;
{routeList.map((item) =&gt; {
if (checkPagePermission(item) &amp;&amp; checkUserPermission(item)) {
return (
&lt;Route
path={item.key.slice(1)}
key={item.key.slice(1)}
element={&lt;AuthComponent&gt;{LazyLoad(LocalRouterMapping[item.key])}&lt;/AuthComponent&gt;}
/&gt;
);
}
return &lt;Route path=&quot;*&quot; key={item.key.slice(1)} element={&lt;AuthComponent&gt;{LazyLoad(&quot;noPermission/NoPermission&quot;)}&lt;/AuthComponent&gt;} /&gt;;
})}
&lt;/Route&gt;
&lt;Route path=&quot;/&quot; element={&lt;Navigate to={&quot;/app&quot;} /&gt;} /&gt;
&lt;Route path=&quot;*&quot; element={LazyLoad(&quot;notFound/NotFound&quot;)} /&gt;
&lt;/Routes&gt;

huangapple
  • 本文由 发表于 2023年3月4日 03:07:28
  • 转载请务必保留本文链接:https://go.coder-hub.com/75630974.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定