React.js路由鉴权时出现[object Promise]类型无效React子元素报错如何解决?
问题根因
- 核心问题:React Router 的
Route组件render属性不支持传入异步函数。你给render传入的async函数执行后会返回 Promise 对象,React 无法将 Promise 识别为合法的可渲染元素,直接触发你遇到的报错。 - 语法错误:
PrivatePage的箭头函数写法混用了隐式返回和显式返回规则:() => (return <Route/>)属于非法语法,要么用() => <Route/>隐式返回JSX,要么用() => { return <Route/> }用大括号包裹函数体后显式返回。 - 路由配置错误:
BasePage中嵌套了子元素的PrivatePage用了错误的自闭合写法}/>,需要改为</PrivatePage>闭合标签。
修复方案
将私有路由改造为带状态的组件,通过useEffect触发异步鉴权逻辑,useState存储鉴权状态,鉴权过程中先返回加载占位内容,拿到鉴权结果后再渲染对应页面或者执行跳转。
修改后的PrivatePage代码
import { useState, useEffect } from 'react'; import { Route, Redirect } from 'react-router-dom'; // 原有Auth方法保持不变即可 function Auth() { return new Promise((resolve, reject) => { let appData = GetAppData(); if (appData.UserToken.length == 0) { reject(-2); } let request = { Token: appData.UserToken, UserId: appData.UserId } axios.post("****UserValidUrl****", request).then(response => { switch (response.data.Type) { case 10: resolve(10); break; case -2: reject(-2); break; case -13: reject(-13); } }).catch(err => { reject(-13); }) }) } const PrivatePage = ({children, ...rest}) => { // 存储鉴权状态:loading标识鉴权中,type存储鉴权结果 const [authState, setAuthState] = useState({ loading: true, type: null }); useEffect(() => { // 组件挂载/路径变化时执行异步鉴权 const checkAuth = async () => { let type = 10; try { type = await Auth(); } catch(e) { type = -13; } setAuthState({ loading: false, type: type }); } checkAuth(); }, [rest.path]); return <Route {...rest} render={({ location }) => { // 鉴权过程中返回加载态,可替换为自定义Loading组件 if (authState.loading) { return <div>权限校验中...</div>; } switch (authState.type) { case 10: return children; case -2: return ( <Redirect to={{ pathname: '/Auth/Login', state: { from: location }, }} /> ); case -13: return ( <Redirect to={{ pathname: '/NotFound', state: { from: location }, }} /> ); default: return <Redirect to="/Auth/Login" />; } }} /> }
修改后的BasePage代码
export default function BasePage() { return ( <div> <BrowserRouter> <Switch> <Route exact path={"/Auth/Login"} component={Login}/> <PrivatePage path={"/"}> <Switch> <Route exact path={"/"} component={Home}/> <Route exact path={"/Dashboard/Home"} component={Home}/> <Route exact path={"/Dashboard/Profile"} component={Profile}/> <Route component={NotFound}/> </Switch> </PrivatePage> </Switch> </BrowserRouter> </div> ); }
优化建议
- 可以对鉴权结果做短时间缓存,避免每次路由切换都发起校验请求,提升页面加载速度。
- 可在
useEffect中添加取消axios请求的逻辑,避免组件提前卸载后仍执行状态更新导致的内存泄漏警告。 - 加载态可以替换为项目通用的全局Loading组件,统一用户体验。
内容的提问来源于stack exchange,提问作者Mohamad Hasan Salmaaniyaan
相关产品推荐
相关产品推荐

