如何在React Router Dom中使用Outlet实现布局并传递props?
适配新版react-router-dom:用Outlet和useOutletContext传递布局props
步骤1:改造AuthLayout组件,使用Outlet并传递上下文
更新AuthLayout,用Outlet替代原来的children,同时通过路由元数据获取每个页面对应的page和img参数,再把这些参数通过Outlet的context属性传递给子组件(若子组件需要使用)。
import { Outlet, useMatch } from 'react-router-dom'; import Logo from 'path-to-your-logo'; // 替换为你的Logo实际路径 const AuthLayout = () => { // 匹配当前嵌套路由,获取路由元数据 const match = useMatch('/*'); const { page, img } = match?.route.meta || {}; return ( <main className={`auth-layout ${page}`}> {/* 子路由内容会渲染在这里 */} <Outlet context={{ page, img }} /> <div className="images"> {img && <img src={img} alt={page} />} <img src={Logo} alt="Logo" className="logo" /> </div> </main> ); };
步骤2:在路由配置中添加元数据
修改App.js的路由配置,给每个子路由添加meta字段,传入对应的page和img值:
import { Routes, Route } from 'react-router-dom'; import AuthLayout from './AuthLayout'; import LoginPage from './LoginPage'; import RegisterPage from './RegisterPage'; import ForgotPassword from './ForgotPassword'; import Verify from './Verify'; // 导入各个页面的图片资源 import LoginImg from 'assets/img/login.svg'; import RegisterImg from 'assets/img/register.svg'; import ForgotImg from 'assets/img/forgot-password.svg'; import VerifyImg from 'assets/img/verify.svg'; function App() { return ( <Routes> <Route element={<AuthLayout />}> <Route path="/login" element={<LoginPage />} meta={{ page: 'login', img: LoginImg }} /> <Route path="/register" element={<RegisterPage />} meta={{ page: 'register', img: RegisterImg }} /> <Route path="/forgotPassword" element={<ForgotPassword />} meta={{ page: 'forgot-password', img: ForgotImg }} /> <Route path="/forgotpassword/verify" element={<Verify />} meta={{ page: 'verify', img: VerifyImg }} /> </Route> </Routes> ); }
步骤3:子组件获取上下文(可选)
如果子组件需要用到page或img参数,用useOutletContext钩子直接获取:
import { useOutletContext } from 'react-router-dom'; const ForgotPassword = () => { // 获取AuthLayout传递的上下文参数 const { page, img } = useOutletContext(); const sendPassword = () => { // 你的业务逻辑 }; return ( <form onClick={sendPassword}> {/* 表单内容 */} </form> ); };
替代方案:直接在AuthLayout中映射路径
如果不想修改路由配置,也可以在AuthLayout里根据当前路径直接映射参数,适合页面数量较少的场景:
import { Outlet, useLocation } from 'react-router-dom'; import Logo from 'path-to-your-logo'; // 导入所有需要的图片资源 import LoginImg from 'assets/img/login.svg'; import RegisterImg from 'assets/img/register.svg'; import ForgotImg from 'assets/img/forgot-password.svg'; import VerifyImg from 'assets/img/verify.svg'; const AuthLayout = () => { const location = useLocation(); // 路径与参数的映射表 const routeMap = { '/login': { page: 'login', img: LoginImg }, '/register': { page: 'register', img: RegisterImg }, '/forgotPassword': { page: 'forgot-password', img: ForgotImg }, '/forgotpassword/verify': { page: 'verify', img: VerifyImg } }; const { page, img } = routeMap[location.pathname] || {}; return ( <main className={`auth-layout ${page}`}> <Outlet context={{ page, img }} /> <div className="images"> {img && <img src={img} alt={page} />} <img src={Logo} alt="Logo" className="logo" /> </div> </main> ); };
内容的提问来源于stack exchange,提问作者Rahil Əliyev
相关产品推荐
相关产品推荐

