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

React中useEffect触发无限循环问题排查求助

无限循环原因分析及解决方法

核心原因

1. data引用持续变化

在useGetTaskAccordingToStatus中,data是通过userQueries?.map(...)生成的数组,每次组件渲染都会创建新的数组引用——哪怕数组里的内容完全没变。第二个useEffect把data作为依赖项,所以每次组件渲染都会触发这个useEffect,调用sFinalState更新finalState状态,进而导致组件再次渲染,重新生成新的data,形成无限循环。

2. columnDataWithTaskProperty的不必要更新

第一个useEffect依赖columnData,每次columnData变化时,都会通过map生成新数组并更新columnDataWithTaskProperty状态。由于数组是引用类型,map每次都会返回新数组,导致columnDataWithTaskProperty的引用持续变化,进一步触发第二个useEffect执行,加剧循环频率。

解决方法

优化useGetTaskAccordingToStatus,稳定data引用

用useMemo缓存data,只有当userQueries中的查询结果真正变化时,才重新生成数组:

const useGetTaskAccordingToStatus = () => {
  const { active_project } = useSelector(projectDataInStore);

  const userQueries = useQueries({
    queries: statesOfTaskManager.map((status) => {
      return {
        queryKey: [status, active_project],
        queryFn: () =>
          customAxiosRequestForGet("/task", {
            status,
            projectName: active_project,
          }),
      };
    }),
  });

  // 用useMemo缓存data,避免每次渲染生成新引用
  const data = useMemo(() => {
    return userQueries?.map((item) => item?.data?.data);
  }, [userQueries]);

  return { data };
};

注:onSuccess回调无需返回数据,React Query会自动处理查询结果,可直接移除。

用衍生状态替代状态更新,彻底消除循环

把columnDataWithTaskProperty和finalState改成useMemo计算的衍生状态,不需要单独用useState存储,避免不必要的状态更新:

const useBoard = () => {
  const { data: columnData } = useGetColumnQuery();
  const { data } = useGetTaskAccordingToStatus();

  // 用useMemo直接计算columnDataWithTaskProperty
  const columnDataWithTaskProperty = useMemo(() => {
    return columnData?.data?.map((item) => ({
      name: item.name,
      _id: item._id,
      tasks: [],
    })) || [];
  }, [columnData]);

  // 用useMemo直接计算finalState,仅在依赖项变化时重新计算
  const finalState = useMemo(() => {
    if (!columnDataWithTaskProperty.length || !data?.length) return [];
    return columnDataWithTaskProperty.map((column) => ({
      ...column,
      tasks: data.flat().filter((task) => task.status === column.name),
    }));
  }, [columnDataWithTaskProperty, data]);

  return {
    finalState,
  };
};

额外检查点

如果statesOfTaskManager是动态生成的数组,也需要用useMemo缓存它,否则会导致useQueries频繁触发重复查询,间接引发循环。

内容的提问来源于stack exchange,提问作者nidhi sharma

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 12:59:56