如何通过cloneElement向Route的组件传递props?
这个问题我之前也碰到过,核心原因是Route组件并不会把自身接收的props直接传递给它的component属性指定的组件——Route内部会自己处理路由相关的props(比如match、location、history),你通过React.cloneElement给Route加上的foo='bar',其实是传给了Route组件本身,而不是Login组件。下面给你几种可行的解决方案:
方案1:使用Route的render属性(React Router v5及以下)
用render代替component,这样你可以手动把路由自带的props和自定义props一起传递给目标组件:
<App> <Route path='/login' render={(routeProps) => <Login {...routeProps} foo='bar' />} /> </App>
这里的routeProps包含了路由相关的match、location、history,通过扩展运算符...把它们和自定义的foo='bar'一起传给Login,这样Login的props里就能同时拿到路由属性和自定义属性了。
方案2:使用Route的children属性(React Router v5及以下)
如果需要不管路径是否匹配都渲染组件(比如侧边栏导航),可以用children属性,用法和render类似:
<App> <Route path='/login' children={(routeProps) => <Login {...routeProps} foo='bar' />} /> </App>
方案3:React Router v6的写法(推荐)
如果你使用的是React Router v6,Route的API有了变化,直接用element属性传入JSX,就可以像普通组件一样传递props:
<App> <Route path='/login' element={<Login foo='bar' />} /> </App>
如果需要路由相关的属性,在Login组件里可以通过useParams、useLocation、useNavigate这些hooks来获取。
方案4:封装自定义Route组件(统一批量传递props)
如果需要给多个Route的组件都传递相同的props,可以封装一个自定义Route组件,避免重复代码:
// 自定义Route组件 function CustomRoute({ component: Component, ...rest }) { return ( <Route {...rest} render={(routeProps) => <Component {...routeProps} foo='bar' />} /> ); } // 在App中使用 <App> <CustomRoute path='/login' component={Login} /> <CustomRoute path='/dashboard' component={Dashboard} /> </App>
这样所有使用CustomRoute的组件都会自动拿到foo='bar'这个props,同时也保留了路由相关的属性。
内容的提问来源于stack exchange,提问作者David

