如何使用React Router实现全应用全局持久化Layout并动态传参
实现全局持久化布局+动态参数适配的方案
核心思路:不需要每个页面手动引入Layout,直接在路由层统一包裹,同时给路由配置扩展布局相关的参数,动态传递给Layout组件即可。
实现步骤
1. 扩展路由配置项,添加布局专属参数
在原有的路由配置中新增layoutProps字段,存储每个页面对应的Layout入参:
const routes = [ { path: "/", component: Home, exact: true, // 新增布局参数 layoutProps: { title: "首页", hasSearchBox: true } }, { path: "/messagelist", component: MessageList, exact: true, layoutProps: { title: "消息列表", hasSearchBox: true } }, { path: "/users", component: Users, exact: true, layoutProps: { title: "用户列表", hasSearchBox: true } }, { path: "/users/new", component: User, exact: true, layoutProps: { title: "新建用户", hasSearchBox: false } }, // 其余路由同理补充对应layoutProps即可 ];
2. 改造RouterProvider组件,统一包裹Layout
在路由逻辑层外层套Layout,同时根据当前访问路径匹配对应路由的布局参数,传入Layout即可:
import { useLocation, Switch, Route, matchPath } from 'react-router-dom'; import { useState } from 'react'; import Layout from './Layout'; import routes from './Route'; function RouterProvider() { const location = useLocation(); // 管理搜索框全局状态 const [searchValue, setSearchValue] = useState(''); // 匹配当前路径对应的路由配置,适配动态路由场景 const matchedRoute = routes.find(route => matchPath(location.pathname, { path: route.path, exact: route.exact }) ); // 取布局参数,可自定义默认值 const { title = '', hasSearchBox = false } = matchedRoute?.layoutProps || {}; return ( {/* Layout放在Switch外层,路由切换时Layout不会重新渲染,实现持久化 */} <Layout title={title} hasSearchBox={hasSearchBox} searchValue={searchValue} onChange={setSearchValue} > <Switch> {routes.map((route, index) => ( <Route path={route.path} component={route.component} exact={route.exact} key={index} /> ))} </Switch> </Layout> ); }
可选优化
如果存在个别页面不需要使用全局布局(比如登录页、404页),可以在路由配置中新增hideLayout: true字段,在RouterProvider中判断如果存在该字段就不包裹Layout即可。
内容的提问来源于stack exchange,提问作者ahmedskulj10
相关产品推荐
相关产品推荐

