React Router(V6) 如何在所有路由中调用加载器函数?

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

React Router(V6) How to call loader funcition in all routes?

问题

Home路由中,我有一个虚拟的加载函数,我想在所有路由中调用相同的加载函数。我不想复制粘贴到所有路由中,有没有一种优雅的方法来做到这一点?

const routes = createBrowserRouter([
    {
        path: '*',
        element: <h1>未找到</h1>
    },
    {
        path: '/',
        element: <Home/>,
        loader: function (data) {
            console.log(data)
            return null;
        },
        action: function () {
            console.log('动作');
        }
    },
    {
        path: '/contact',
        element: <Contact/>
    },
    {
        path: '/admin',
        children: [
            {path: 'dashboard', element: <Dashboard/>},
            {path: 'manage', element: <Dashboard/>},
            {path: 'manage/user/:userId', element: <Dashboard/>},
            {path: 'settings', element: <Dashboard/>},
        ]
    }
])
英文:

Simple question as u can see i have dummy loader function in Home route i want to call same loader function in all routes. i do not want to copy paste to all routes is there a elegant way to do that?

const routes = createBrowserRouter([
    {
        path: &#39;*&#39;,
        element: &lt;h1&gt;Not found&lt;/h1&gt;
    },
    {
        path: &#39;/&#39;,
        element: &lt;Home/&gt;,
        loader: function (data) {
            console.log(data)
            return null;
        },
        action: function () {
            console.log(&#39;action&#39;);
        }
    },
    {
        path: &#39;/contact&#39;,
        element: &lt;Contact/&gt;
    },
    {
        path: &#39;/admin&#39;,
        children: [
            {path: &#39;dashboard&#39;, element: &lt;Dashboard/&gt;},
            {path: &#39;manage&#39;, element: &lt;Dashboard/&gt;},
            {path: &#39;manage/user/:userId&#39;, element: &lt;Dashboard/&gt;},
            {path: &#39;settings&#39;, element: &lt;Dashboard/&gt;},
        ]
    }
])```

</details>


# 答案1
**得分**: 1

一种解决方案:通过JavaScript函数递归地向路由对象添加`loader`属性。

```jsx
import { createRoot } from "react-dom/client";
import {
  createBrowserRouter,
  RouterProvider,
  useLoaderData
} from "react-router-dom";

function Home() {
  const data = useLoaderData();
  console.log("home loader data:", data);
  return <div>home</div>;
}
function Contact() {
  const data = useLoaderData();
  console.log("contact loader data:", data);
  return <div>contact</div>;
}

function Dashboard() {
  const data = useLoaderData();
  console.log("dashboard loader data:", data);
  return <div>dashboard</div>;
}

function someLoader() {
  return "some data";
}

function attachLoaderRecursively(routes, loader) {
  for (const route of routes) {
    if (route.path) {
      route.loader = loader;
    }
    if (route.children?.length) {
      attachLoaderRecursively(route.children, loader);
    }
  }
  return routes;
}

const routes = [
  {
    path: "/",
    element: <Home />
  },
  {
    path: "/contact",
    element: <Contact />
  },
  {
    path: "/admin",
    children: [
      { path: "dashboard", element: <Dashboard /> },
      { path: "manage", element: <div>manage</div> },
      { path: "manage/user/:userId", element: <div>manage user by id</div> },
      { path: "settings", element: <div>settings</div> }
    ]
  }
];

const routesWithLoader = attachLoaderRecursively(routes, someLoader);
console.log(routesWithLoader);
const router = createBrowserRouter(routesWithLoader);

const rootElement = document.getElementById("root");
const root = createRoot(rootElement);

root.render(<RouterProvider router={router} />);

React Router(V6) 如何在所有路由中调用加载器函数?

codesandbox

英文:

One solution: Add the loader property to route object recursively by a JavaScript function.

import { createRoot } from &quot;react-dom/client&quot;;
import {
  createBrowserRouter,
  RouterProvider,
  useLoaderData
} from &quot;react-router-dom&quot;;

function Home() {
  const data = useLoaderData();
  console.log(&quot;home loader data &quot;, data);
  return &lt;div&gt;home&lt;/div&gt;;
}
function Contact() {
  const data = useLoaderData();
  console.log(&quot;contact loader data &quot;, data);
  return &lt;div&gt;contact&lt;/div&gt;;
}

function Dashboard() {
  const data = useLoaderData();
  console.log(&quot;dashboard loader data &quot;, data);
  return &lt;div&gt;dashboard&lt;/div&gt;;
}

function someLoader() {
  return &quot;some data&quot;;
}

function attachLoaderRecursively(routes, loader) {
  for (const route of routes) {
    if (route.path) {
      route.loader = loader;
    }
    if (route.children?.length) {
      attachLoaderRecursively(route.children, loader);
    }
  }
  return routes;
}

const routes = [
  {
    path: &quot;/&quot;,
    element: &lt;Home /&gt;
  },
  {
    path: &quot;/contact&quot;,
    element: &lt;Contact /&gt;
  },
  {
    path: &quot;/admin&quot;,
    children: [
      { path: &quot;dashboard&quot;, element: &lt;Dashboard /&gt; },
      { path: &quot;manage&quot;, element: &lt;div&gt;manage&lt;/div&gt; },
      { path: &quot;manage/user/:userId&quot;, element: &lt;div&gt;manage user by id&lt;/div&gt; },
      { path: &quot;settings&quot;, element: &lt;div&gt;settings&lt;/div&gt; }
    ]
  }
];

const routesWithLoader = attachLoaderRecursively(routes, someLoader);
console.log(routesWithLoader);
const router = createBrowserRouter(routesWithLoader);

const rootElement = document.getElementById(&quot;root&quot;);
const root = createRoot(rootElement);

root.render(&lt;RouterProvider router={router} /&gt;);

React Router(V6) 如何在所有路由中调用加载器函数?

codesandbox

huangapple
  • 本文由 发表于 2023年7月27日 19:48:19
  • 转载请务必保留本文链接:https://go.coder-hub.com/76779427.html
匿名

发表评论

匿名网友

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

确定