英文:
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: '*',
element: <h1>Not found</h1>
},
{
path: '/',
element: <Home/>,
loader: function (data) {
console.log(data)
return null;
},
action: function () {
console.log('action');
}
},
{
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/>},
]
}
])```
</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} />);
英文:
One solution: Add the loader
property to route object recursively by a JavaScript function.
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} />);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论