React Router(V6)如何在所有路由中调用loader函数?
优雅复用React Router的Loader和Action函数
方案1:提取公共函数直接复用
先把loader和action抽成独立函数,之后在需要的路由里直接引用就行,不用重复写代码:
// 提取公共的loader和action const commonLoader = (data) => { console.log(data); return null; }; const commonAction = () => { console.log('action'); }; const routes = createBrowserRouter([ { path: '*', element: <h1>Not found</h1>, loader: commonLoader, action: commonAction }, { path: '/', element: <Home/>, loader: commonLoader, action: commonAction }, { path: '/contact', element: <Contact/>, loader: commonLoader, action: commonAction }, { path: '/admin', loader: commonLoader, // 父路由添加后,子路由渲染前会自动执行这个loader action: commonAction, children: [ {path: 'dashboard', element: <Dashboard/>}, {path: 'manage', element: <Dashboard/>}, {path: 'manage/user/:userId', element: <Dashboard/>}, {path: 'settings', element: <Dashboard/>}, ] } ])
方案2:用布局路由统一包裹(推荐)
如果大部分路由都需要复用逻辑,可以用一个空布局路由把所有路由包起来,把loader/action放在这个父路由上,所有子路由(包括嵌套的)都会自动触发父路由的loader和action,不用逐个添加:
const commonLoader = (data) => { console.log(data); return null; }; const commonAction = () => { console.log('action'); }; const routes = createBrowserRouter([ // 这个根路由仅执行公共逻辑,不渲染额外元素 { path: '/', loader: commonLoader, action: commonAction, children: [ { path: '*', element: <h1>Not found</h1> }, { path: '/', element: <Home/> }, { 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/>}, ] } ] } ])
提示:如果某个路由需要自定义loader/action,直接在该路由上定义即可,React Router会优先执行当前路由的逻辑,再执行父路由的。
方案3:写工具函数批量处理路由配置
如果路由数量多,还可以写个工具函数,遍历路由数组自动给每个路由注入公共的loader和action:
const commonLoader = (data) => { console.log(data); return null; }; const commonAction = () => { console.log('action'); }; // 递归处理路由,给每个路由添加公共逻辑(已有自定义逻辑的路由保留自己的) const addCommonHandlers = (routes) => { return routes.map(route => { const updatedRoute = { ...route, loader: route.loader || commonLoader, action: route.action || commonAction }; // 处理嵌套子路由 if (route.children) { updatedRoute.children = addCommonHandlers(route.children); } return updatedRoute; }); }; // 原始路由配置 const rawRoutes = [ { 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/>}, ] } ]; // 生成最终路由 const routes = createBrowserRouter(addCommonHandlers(rawRoutes));
内容的提问来源于stack exchange,提问作者CodeX
相关产品推荐
相关产品推荐

