You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 19:13:27