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

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

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.

  1. const [routeList, setRouteList] = useState([]);
  2. useEffect(() => {
  3. Promise.all([
  4. axios.get("http://localhost:5000/rights"),
  5. axios.get("http://localhost:5000/children")
  6. ])
  7. .then((res) => {
  8. setRouteList([...res[0].data, ...res[1].data]);
  9. });
  10. }, []);
  1. const element = useRoutes([
  2. {
  3. path: "/login",
  4. element: LazyLoad("login/Login"),
  5. },
  6. {
  7. path: "/app",
  8. element: <AuthComponent>
  9. {LazyLoad("sandbox/Sandbox")}</AuthComponent>,
  10. children: [
  11. {
  12. path: "",
  13. element: <Redirect to="/app/home" />,
  14. },
  15. routeList.map((item) => {
  16. `path: ${item.key}, element:
  17. ${LocalRouterMapping[item.key]}`;
  18. }),
  19. {
  20. path: "*",
  21. element:
  22. LazyLoad("noPermission/NoPermission"),
  23. },
  24. ],
  25. },
  26. ]);

But I get an error for doing this

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

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?

  1. const LazyLoad = (path) => {
  2. const Comp = React.lazy(() =>
  3. import(`../views/${path}`));
  4. return (
  5. <React.Suspense fallback={<Loading...>}>
  6. <Comp />
  7. </React.Suspense>
  8. );
  9. };

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

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

Here's my LocalRouterMapping:

  1. const LocalRouterMapping = {
  2. "/home": "dashboard/Dashboard",
  3. "/user-manage/list": "user-manage/UserList",
  4. "/access-manage/access/list": "access-manage/AccessList",
  5. "/access-manage/role/list": "access-manage/RoleList",
  6. "/news-manage/add": "inventory/CreateInventory",
  7. "/news-manage/draft": "inventory/InventoryDraft",
  8. "/news-manage/category": "inventory/InventoryCategory",
  9. "/audit-manage/audit": "audit/AuditInventory",
  10. "/audit-manage/list": "audit/AuditList",
  11. };

These are the data from axios datafromAxios.

Here's my whole code:

  1. import React, { useEffect, useState } from "react";
  2. import { useRoutes } from "react-router-dom";
  3. import Redirect from "../components/Redirect";
  4. import axios from "axios";
  5. const LocalRouterMapping = {
  6. "/home": "dashboard/Dashboard",
  7. "/user-manage/list": "user-manage/UserList",
  8. "/access-manage/access/list": "access-manage/AccessList",
  9. "/access-manage/role/list": "access-manage/RoleList",
  10. "/news-manage/add": "inventory/CreateInventory",
  11. "/news-manage/draft": "inventory/InventoryDraft",
  12. "/news-manage/category": "inventory/InventoryCategory",
  13. "/audit-manage/audit": "audit/AuditInventory",
  14. "/audit-manage/list": "audit/AuditList",
  15. };
  16. export default function IndexRouter() {
  17. const [routeList, setRouteList] = useState([]);
  18. useEffect(() => {
  19. Promise.all([axios.get("http://localhost:5000/rights"), axios.get("http://localhost:5000/children")]).then((res) => {
  20. const combinedRoutes = [...res[0].data, ...res[1].data];
  21. setRouteList(combinedRoutes.filter((item) => LocalRouterMapping[item.key]));
  22. });
  23. }, []);
  24. const element = useRoutes([
  25. {
  26. path: "/login",
  27. element: LazyLoad("login/Login"),
  28. },
  29. {
  30. path: "/app",
  31. element: <AuthComponent> {LazyLoad("sandbox/Sandbox")} </AuthComponent>,
  32. children: [
  33. {
  34. path: "",
  35. element: <Redirect to="/app/home" />,
  36. },
  37. routeList.map((item) => ({
  38. path: item.key.slice(1),
  39. element: <AuthComponent>{LazyLoad(LocalRouterMapping[item.key])}</AuthComponent>,
  40. })),
  41. {
  42. path: "*",
  43. element: LazyLoad("noPermission/NoPermission"),
  44. },
  45. ],
  46. },
  47. {
  48. path: "/dashboard",
  49. element: <AuthComponent>{LazyLoad("dashboard/Dashboard")}</AuthComponent>,
  50. },
  51. {
  52. path: "/product",
  53. element: <AuthComponent>
  54. {LazyLoad("dashboard/Dashboard")}
  55. </AuthComponent>,
  56. },
  57. {
  58. path: "/",
  59. element: <Redirect to="/app" />,
  60. },
  61. {
  62. path: "*",
  63. element: LazyLoad("notFound/NotFound"),
  64. },
  65. ]);
  66. return element;
  67. }
  68. function AuthComponent({ children }) {
  69. const isLogin = localStorage.getItem("token");
  70. return isLogin ? children : <Redirect to="/login" />;
  71. }
  72. const LazyLoad = (path) => {
  73. const Comp = React.lazy(() => import(`../views/${path}`));
  74. return (
  75. <React.Suspense fallback={<Loading...>}>
  76. <Comp />
  77. </React.Suspense>
  78. );
  79. };
英文:

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.

  1. const [routeList, setRouteList] = useState([]);
  2. useEffect(() =&gt; {
  3. Promise.all([
  4. axios.get(&quot;http://localhost:5000/rights&quot;),
  5. axios.get(&quot;http://localhost:5000/children&quot;)
  6. ])
  7. .then((res) =&gt; {
  8. setRouteList([...res[0].data, ...res[1].data]);
  9. });
  10. }, []);
  1. const element = useRoutes([
  2. {
  3. path: &quot;/login&quot;,
  4. element: LazyLoad(&quot;login/Login&quot;),
  5. },
  6. {
  7. path: &quot;/app&quot;,
  8. element: &lt;AuthComponent&gt;
  9. {LazyLoad(&quot;sandbox/Sandbox&quot;)}&lt;/AuthComponent&gt;,
  10. children: [
  11. {
  12. path: &quot;&quot;,
  13. element: &lt;Redirect to=&quot;/app/home&quot; /&gt;,
  14. },
  15. routeList.map((item) =&gt; {
  16. `path: ${item.key}, element:
  17. ${LocalRouterMapping[item.key]}`;
  18. }),
  19. {
  20. path: &quot;*&quot;,
  21. element:
  22. LazyLoad(&quot;noPermission/NoPermission&quot;),
  23. },
  24. ],
  25. },
  26. ]);

But I get an error for doing this

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

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?

  1. const LazyLoad = (path) =&gt; {
  2. const Comp = React.lazy(() =&gt;
  3. import(`../views/${path}`));
  4. return (
  5. &lt;React.Suspense fallback={&lt;&gt;Loading...&lt;/&gt;}&gt;
  6. &lt;Comp /&gt;
  7. &lt;/React.Suspense&gt;
  8. );
  9. };

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

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

Here's my LocalRouterMapping

  1. const LocalRouterMapping = {
  2. &quot;/home&quot;: &quot;dashboard/Dashboard&quot;,
  3. &quot;/user-manage/list&quot;: &quot;user-manage/UserList&quot;,
  4. &quot;/access-manage/access/list&quot;: &quot;access-manage/AccessList&quot;,
  5. &quot;/access-manage/role/list&quot;: &quot;access-manage/RoleList&quot;,
  6. &quot;/news-manage/add&quot;: &quot;inventory/CreateInventory&quot;,
  7. &quot;/news-manage/draft&quot;: &quot;inventory/InventoryDraft&quot;,
  8. &quot;/news-manage/category&quot;: &quot;inventory/InventoryCategory&quot;,
  9. &quot;/audit-manage/audit&quot;: &quot;audit/AuditInventory&quot;,
  10. &quot;/audit-manage/list&quot;: &quot;audit/AuditList&quot;,
  11. };

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

Here's my whole code

  1. import React, { useEffect, useState } from &quot;react&quot;;
  2. import { useRoutes } from &quot;react-router-dom&quot;;
  3. import Redirect from &quot;../components/Redirect&quot;;
  4. import axios from &quot;axios&quot;;
  5. const LocalRouterMapping = {
  6. &quot;/home&quot;: &quot;dashboard/Dashboard&quot;,
  7. &quot;/user-manage/list&quot;: &quot;user-manage/UserList&quot;,
  8. &quot;/access-manage/access/list&quot;: &quot;access-manage/AccessList&quot;,
  9. &quot;/access-manage/role/list&quot;: &quot;access-manage/RoleList&quot;,
  10. &quot;/news-manage/add&quot;: &quot;inventory/CreateInventory&quot;,
  11. &quot;/news-manage/draft&quot;: &quot;inventory/InventoryDraft&quot;,
  12. &quot;/news-manage/category&quot;: &quot;inventory/InventoryCategory&quot;,
  13. &quot;/audit-manage/audit&quot;: &quot;audit/AuditInventory&quot;,
  14. &quot;/audit-manage/list&quot;: &quot;audit/AuditList&quot;,};
  15. export default function IndexRouter() {
  16. const [routeList, setRouteList] = useState([]);
  17. useEffect(() =&gt; {Promise.all([axios.get(&quot;http://localhost:5000/rights&quot;), axios.get(&quot;http://localhost:5000/children&quot;)]).then((res) =&gt; {
  18. const combinedRoutes = [...res[0].data, ...res[1].data];
  19. setRouteList(combinedRoutes.filter((item) =&gt; LocalRouterMapping[item.key]));
  20. });
  21. }, []);
  22. const element = useRoutes([
  23. {
  24. path: &quot;/login&quot;,
  25. element: LazyLoad(&quot;login/Login&quot;),
  26. },
  27. {
  28. path: &quot;/app&quot;,
  29. element: &lt;AuthComponent&gt; {LazyLoad(&quot;sandbox/Sandbox&quot;)} &lt;/AuthComponent&gt;,
  30. children: [
  31. {
  32. path: &quot;&quot;,
  33. element: &lt;Redirect to=&quot;/app/home&quot; /&gt;,
  34. },
  35. routeList.map((item) =&gt; ({
  36. path: item.key.slice(1),
  37. element: &lt;AuthComponent&gt;{LazyLoad(LocalRouterMapping[item.key])}&lt;/AuthComponent&gt;,
  38. })),
  39. {
  40. path: &quot;*&quot;,
  41. element: LazyLoad(&quot;noPermission/NoPermission&quot;),
  42. },
  43. ],
  44. },
  45. {
  46. path: &quot;/dashboard&quot;,
  47. element: &lt;AuthComponent&gt;{LazyLoad(&quot;dashboard/Dashboard&quot;)}&lt;/AuthComponent&gt;,
  48. },
  49. {
  50. path: &quot;/product&quot;,
  51. element: &lt;AuthComponent&gt;
  52. {LazyLoad(&quot;dashboard/Dashboard&quot;)}
  53. &lt;/AuthComponent&gt;,
  54. },
  55. {
  56. path: &quot;/&quot;,
  57. element: &lt;Redirect to=&quot;/app&quot; /&gt;,
  58. },
  59. {
  60. path: &quot;*&quot;,
  61. element: LazyLoad(&quot;notFound/NotFound&quot;),
  62. },
  63. ]);
  64. return element;
  65. }
  66. function AuthComponent({ children }) {
  67. const isLogin = localStorage.getItem(&quot;token&quot;);
  68. return isLogin ? children : &lt;Redirect to=&quot;/login&quot; /&gt;;
  69. }
  70. const LazyLoad = (path) =&gt; {
  71. const Comp = React.lazy(() =&gt; import(`../views/${path}`));
  72. return (
  73. &lt;React.Suspense fallback={&lt;&gt;Loading...&lt;/&gt;}&gt;
  74. &lt;Comp /&gt;
  75. &lt;/React.Suspense&gt;
  76. );
  77. };

答案1

得分: 0

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

示例:

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

完整的代码:

  1. const element = useRoutes([
  2. {
  3. path: "/login",
  4. element: LazyLoad("login/Login"),
  5. },
  6. {
  7. path: "/app",
  8. element: <AuthComponent>{LazyLoad("sandbox/Sandbox")}</AuthComponent>,
  9. children: [
  10. {
  11. index: true,
  12. element: <Redirect to="/app/home" />,
  13. },
  14. routeList
  15. // 确保存在组件映射
  16. .filter(item => LocalRouterMapping[item.key])
  17. // 映射到 RouteObject 属性
  18. .map((item) => ({
  19. path: item.key,
  20. element: LazyLoad(LocalRouterMapping[item.key]),
  21. })),
  22. {
  23. path: "*",
  24. element: LazyLoad("noPermission/NoPermission"),
  25. },
  26. ],
  27. },
  28. ]);
英文:

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:

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

Complete code:

  1. const element = useRoutes([
  2. {
  3. path: &quot;/login&quot;,
  4. element: LazyLoad(&quot;login/Login&quot;),
  5. },
  6. {
  7. path: &quot;/app&quot;,
  8. element: &lt;AuthComponent&gt;{LazyLoad(&quot;sandbox/Sandbox&quot;)}&lt;/AuthComponent&gt;,
  9. children: [
  10. {
  11. index: true,
  12. element: &lt;Redirect to=&quot;/app/home&quot; /&gt;,
  13. },
  14. routeList
  15. // Ensure there is component mapping
  16. .filter(item =&gt; LocalRouterMapping[item.key])
  17. // Map to RouteObject properties
  18. .map((item) =&gt; ({
  19. path: item.key,
  20. element: LazyLoad(LocalRouterMapping[item.key]),
  21. })),
  22. {
  23. path: &quot;*&quot;,
  24. element: LazyLoad(&quot;noPermission/NoPermission&quot;),
  25. },
  26. ],
  27. },
  28. ]);

答案2

得分: 0

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

  1. const LocalRouterMapping = {
  2. "/home": "dashboard/Dashboard",
  3. "/user-manage/list": "user-manage/UserList",
  4. "/access-manage/access/list": "access-manage/AccessList",
  5. "/access-manage/role/list": "access-manage/RoleList",
  6. "/inventory-manage/add": "inventory/CreateInventory",
  7. "/inventory-manage/list": "inventory/InventoryList",
  8. "/inventory-manage/preview/:id": "inventory/InventoryDetails",
  9. "/inventory-manage/update/:id": "inventory/InventoryUpdate",
  10. "/inventory-manage/category": "inventory/InventoryCategory",
  11. };
  12. <Routes>
  13. <Route path="/login" element={LazyLoad("login/Login")} />
  14. <Route path="/app" element={LazyLoad("sandbox/Sandbox")}>
  15. <Route path="" element={<Navigate to="home" />} />
  16. <Route path="*" element={<AuthComponent>{LazyLoad("noPermission/NoPermission")}</AuthComponent>} />
  17. {routeList.map((item) => {
  18. if (checkPagePermission(item) && checkUserPermission(item)) {
  19. return (
  20. <Route
  21. path={item.key.slice(1)}
  22. key={item.key.slice(1)}
  23. element={<AuthComponent>{LazyLoad(LocalRouterMapping[item.key])}</AuthComponent>}
  24. />
  25. );
  26. }
  27. return <Route path="*" key={item.key.slice(1)} element={<AuthComponent>{LazyLoad("noPermission/NoPermission")}</AuthComponent>} />;
  28. })}
  29. </Route>
  30. <Route path="/" element={<Navigate to="/app" />} />
  31. <Route path="*" element={LazyLoad("notFound/NotFound")} />
  32. </Routes>
英文:

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

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

  1. const LocalRouterMapping = {
  2. &quot;/home&quot;: &quot;dashboard/Dashboard&quot;,
  3. &quot;/user-manage/list&quot;: &quot;user-manage/UserList&quot;,
  4. &quot;/access-manage/access/list&quot;: &quot;access-manage/AccessList&quot;,
  5. &quot;/access-manage/role/list&quot;: &quot;access-manage/RoleList&quot;,
  6. &quot;/inventory-manage/add&quot;: &quot;inventory/CreateInventory&quot;,
  7. &quot;/inventory-manage/list&quot;: &quot;inventory/InventoryList&quot;,
  8. &quot;/inventory-manage/preview/:id&quot;: &quot;inventory/InventoryDetails&quot;,
  9. &quot;/inventory-manage/update/:id&quot;: &quot;inventory/InventoryUpdate&quot;,
  10. &quot;/inventory-manage/category&quot;: &quot;inventory/InventoryCategory&quot;,
  11. };
  12. &lt;Routes&gt;
  13. &lt;Route path=&quot;/login&quot; element={LazyLoad(&quot;login/Login&quot;)} /&gt;
  14. &lt;Route path=&quot;/app&quot; element={LazyLoad(&quot;sandbox/Sandbox&quot;)}&gt;
  15. &lt;Route path=&quot;&quot; element={&lt;Navigate to={&quot;home&quot;} /&gt;} /&gt;
  16. &lt;Route path=&quot;*&quot; element={&lt;AuthComponent&gt;{LazyLoad(&quot;noPermission/NoPermission&quot;)}&lt;/AuthComponent&gt;} /&gt;
  17. {routeList.map((item) =&gt; {
  18. if (checkPagePermission(item) &amp;&amp; checkUserPermission(item)) {
  19. return (
  20. &lt;Route
  21. path={item.key.slice(1)}
  22. key={item.key.slice(1)}
  23. element={&lt;AuthComponent&gt;{LazyLoad(LocalRouterMapping[item.key])}&lt;/AuthComponent&gt;}
  24. /&gt;
  25. );
  26. }
  27. return &lt;Route path=&quot;*&quot; key={item.key.slice(1)} element={&lt;AuthComponent&gt;{LazyLoad(&quot;noPermission/NoPermission&quot;)}&lt;/AuthComponent&gt;} /&gt;;
  28. })}
  29. &lt;/Route&gt;
  30. &lt;Route path=&quot;/&quot; element={&lt;Navigate to={&quot;/app&quot;} /&gt;} /&gt;
  31. &lt;Route path=&quot;*&quot; element={LazyLoad(&quot;notFound/NotFound&quot;)} /&gt;
  32. &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:

确定