React-Router出现Functions are not valid as a React child报错及路由props获取问题
问题原因&解决方案
1. 修复语法错误(触发「Functions are not valid as a React child」警告的核心原因)
你代码中的Redirect组件标签未正确闭合,缺失了/>,导致JSX解析异常,相当于直接返回了Redirect函数本身而非组件实例,触发了该警告。
修复后对应代码段:
isLoggedIn.loggedIn ? <Component {...routerProps} {...rest} /> : <Redirect to={{pathname:'/login'}} />
同时建议给嵌套三元运算符添加括号,避免优先级导致的逻辑错误,提升可读性:
return ( <Route {...rest} render={(routerProps) => { return isLoggedIn.loaded ? ( isLoggedIn.loggedIn ? <Component {...routerProps} {...rest} /> : <Redirect to={{pathname:'/login'}} /> ) : ( <h1>Loading Page</h1> ) }} /> )
2. 修复useEffect的非法async回调
useEffect的入参函数不能直接声明为async,因为async函数默认返回Promise,而useEffect期望的返回值只能是清理函数或者undefined,这会导致隐式运行异常。
调整写法如下:
useEffect(() => { // 内部声明async函数执行异步逻辑 const checkLoginStatus = async () => { const userStatus = await validateUserLoggedIn(); setLoggedIn({loggedIn: userStatus, loaded: true}); } checkLoginStatus(); }, [])
3. 组件无法获取router props的问题排查
你当前代码已经通过render回调的routerProps把路由属性透传给了目标组件,如果仍然无法访问,可按以下两点排查:
- 确认你的
react-router-dom版本为v5.x,v6版本已经移除了Route的render属性、Redirect组件,写法完全不同,如果是v6版本需要调整整体实现逻辑。 - 如果是类组件,可以直接在组件内通过
this.props访问history/location/match;如果是函数组件,优先使用react-router-dom提供的useHistory/useLocation/useParams等Hook获取路由属性,比透传props更稳定。
修复后完整的ProtectedRoute代码
const ProtectedRoute = ({component: Component, ...rest}) => { const [isLoggedIn, setLoggedIn] = useState({loggedIn: false, loaded: false}) useEffect(() => { const checkLoginStatus = async () => { const userStatus = await validateUserLoggedIn(); setLoggedIn({loggedIn: userStatus, loaded: true}); } checkLoginStatus(); }, []) return( <Route {...rest} render={(routerProps) => isLoggedIn.loaded ? ( isLoggedIn.loggedIn ? <Component {...routerProps} {...rest} /> : <Redirect to={{pathname: '/login'}} /> ) : ( <h1>Loading Page</h1> ) } /> ) }
内容的提问来源于stack exchange,提问作者B.Anup
相关产品推荐
相关产品推荐

