React项目如何为路由包装器LoggedInWrapper传递任意组件实现渲染
错误原因说明
你尝试的LoggedInWrapper<MyOtherComponent>是不符合TSX语法的写法,<>在这里会被识别为JSX标签的起始标识,无法直接用来向组件传递目标组件参数。下面提供两种可直接落地的改造方案:
方案1:调整Wrapper为插槽形式(灵活度最高,推荐)
第一步:修改LoggedInWrapper实现
改为接收children插槽参数,无需固定传入component:
export const LoggedInWrapper = ({ children }: { children: React.ReactNode }) => { return ( <div className="content flex-column-fluid" id="kt_content"> {/* 面包屑、菜单公共代码放这 */} <div className="row"> <div className="col-xl-12"> {children} </div> </div> ) }
第二步:扩展PrivateRoute支持布局包裹
新增可选的wrapper参数,自动处理需要公共布局的页面:
export const PrivateRoute = ({ component: Component, wrapper: Wrapper, ...rest }: any) => { const { currentUser } = useAuth() return ( <Route {...rest} render={props => { if (currentUser) { const pageContent = <Component {...props} /> // 传了wrapper就用布局包裹,否则直接渲染页面 return Wrapper ? <Wrapper>{pageContent}</Wrapper> : pageContent } return <Redirect to="/login" />; }} /> ) }
第三步:路由配置写法
{/* 需要公共布局的私有路由,传入wrapper参数即可 */} <PrivateRoute path="/admin-edit-member/:id" component={MyOtherComponent} wrapper={LoggedInWrapper} /> <PrivateRoute path="/my-path/:id" component={MyPathComponent} wrapper={LoggedInWrapper} /> {/* 公开路由保持原有写法不变 */} <Route path="/login" exact component={Login} /> <Route path="/forgot-password" exact component={ForgotPassword} />
方案2:高阶组件写法(无需修改现有PrivateRoute,改造成本最低)
第一步:改造LoggedInWrapper为高阶组件
// 接收页面组件为参数,返回包裹了公共布局的新组件 export const withLoggedInWrapper = <P extends object>(Component: React.ComponentType<P>) => { return (props: P) => ( <div className="content flex-column-fluid" id="kt_content"> {/* 面包屑、菜单公共代码放这 */} <div className="row"> <div className="col-xl-12"> <Component {...props} /> </div> </div> ) }
第二步:路由配置写法
直接用高阶组件包裹目标页面组件传入即可:
<PrivateRoute path="/admin-edit-member/:id" component={withLoggedInWrapper(MyOtherComponent)} />
内容的提问来源于stack exchange,提问作者Andurit
相关产品推荐
相关产品推荐

