React函数组件PrivateRoute条件渲染未触发重渲染问题求助
问题根因分析
- 核心问题出在首次渲染的优先级高于异步请求:组件第一次挂载时,
condition初始值是空字符串'',属于假值,渲染逻辑会直接返回<Redirect>组件。而React路由的<Redirect>只要被渲染就会立刻触发路由跳转,不会等待getUserAccess异步请求返回结果。 - 跳转执行后,当前
PrivateRoute组件会直接被卸载,后续异步请求成功调用setCondition时,目标组件已经不存在于DOM树中,自然不会触发任何重渲染,你设置的state也就不会生效。 - 额外的小问题:你当前把
condition加入useEffect依赖,会导致condition每次变为空值时都重复发起权限请求,属于不必要的逻辑。
修复方案
核心思路是增加加载状态,在接口请求未完成时渲染加载占位,不直接返回Redirect,等权限接口拿到结果后再判断走路由还是跳转,修改后代码如下:
const PrivateRoute = props => { // 初始值设为null,明确区分「未请求权限」和「校验后无权限」两种状态 const [condition, setCondition] = useState(null); // 只在组件挂载时发起一次权限请求即可,不需要把condition加进依赖 useEffect(() => { const getUserAccess = async () => { try { const response = await axios.get("/some-api"); const status = response.data; /* status will either be true or false */ setCondition(status); } catch (err) { // 接口报错的场景统一按无权限处理 setCondition(false); } } getUserAccess(); }, []); // 请求未完成时渲染加载态,不触发跳转 if (condition === null) { return <div>权限校验中...</div>; } return condition ? ( <Route path={props.path} exact={props.exact} component={props.component}/> ) : ( <Redirect to="/unauthorized/login"/> ); }; export default PrivateRoute;
内容的提问来源于stack exchange,提问作者slashdot
相关产品推荐
相关产品推荐

