ReactJS中使用异步函数无法用更新后的常量值渲染组件
问题分析
你的代码核心问题是权限数据加载完成前就执行了路由判断:
permissions初始值是空数组,组件第一次渲染时,permissions.includes(route)必然返回false,直接触发<Navigate to="/" />跳转。- 异步加载权限的逻辑在
useEffect中,这部分代码会在组件首次渲染完成后才执行,等permissions更新时,页面已经完成跳转,后续的重渲染无法改变这个结果。
修复方案
添加加载状态,在权限数据未加载完成时,先显示加载占位(而非直接跳转),等数据就绪后再进行权限判断:
import { Navigate } from "react-router-dom"; import { useSelector } from "react-redux"; import configService from "../_configService"; import { useEffect, useState } from "react"; const ProtectedRoute = (Component: any, route: string) => { // 注意:这里需要确认useSelector是否正确获取用户状态,示例中直接取state可能拿到整个store,建议改为state.user或对应字段 const currentUser: any = useSelector((state) => state); const [permissions, setPermissions] = useState<string[]>([]); const [isLoading, setIsLoading] = useState(true); useEffect(() => { const config = new configService(); config.loadConfigData() .then(() => { setPermissions(config.Permissions); }) .catch((err) => { // 可添加错误处理逻辑,比如打印日志、提示用户等 console.error("加载权限失败:", err); }) .finally(() => { // 无论成功失败,都结束加载状态 setIsLoading(false); }); }, []); // 加载中时显示占位内容 if (isLoading) { return <div>加载中...</div>; // 替换成你的加载组件(如Spinner) } // 权限判断逻辑:用户存在且路由在权限列表内则渲染组件,否则跳转 return currentUser && permissions.includes(route) ? <Component /> : <Navigate to="/" />; }; export default ProtectedRoute;
额外优化建议
- 移除冗余的
render函数:原代码中render函数只是直接返回传入的组件,完全可以省略,直接返回<Component />即可。 - 确认用户状态获取逻辑:
useSelector((state) => state)会返回整个Redux store对象,通常你需要的是具体的用户字段(比如state.user),请根据你的store结构调整这部分代码。 - 处理加载失败场景:如果权限加载失败,可以根据业务需求决定是跳转首页、显示错误页面还是允许访问默认权限。
内容的提问来源于stack exchange,提问作者tanaya sharma
相关产品推荐
相关产品推荐

