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

React如何避免useEffect内调用函数触发最大更新深度超限错误

Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.

问题根因

  • 父组件定义的pushToArrayOfDocuments函数未做稳定化处理,每次父组件渲染时都会生成全新的函数实例。该函数作为setDocument属性传给子组件后,会被识别为依赖变更,触发子组件的useEffect执行。
  • 子组件useEffect执行setDocument(file)后会更新父组件的arrayOfDocuments状态,导致父组件重新渲染,再次生成新的pushToArrayOfDocuments实例,形成无限渲染循环。

解决方案

1. 用useCallback稳定父组件函数引用

在父组件中使用useCallback包裹pushToArrayOfDocuments,因为函数内部调用setArrayOfDocuments时使用了函数式更新,不依赖外部状态,所以依赖数组可以留空,确保函数引用永远不变:

import { useCallback, useState } from 'react';

// 原有状态定义不变
const [arrayOfDocuments, setArrayOfDocuments] = useState([]);

// 用useCallback包裹函数
const pushToArrayOfDocuments = useCallback((obj) => {
  if (obj.filename && obj.file && obj.expiredate && obj.doctype) {
    setArrayOfDocuments((oldArr) => {
      const arr = oldArr.slice();
      const index = arr.map((e) => e.filename).indexOf(obj.filename);
      if (index !== -1) {
        arr[index] = obj;
      } else {
        arr.push(obj);
      }
      return arr;
    });
  }
}, []);

2. 子组件useEffect增加变更校验(可选优化)

如果file是引用类型对象,可在useEffect中增加有效性判断,只有当file真的发生业务层面的变更时才调用setDocument,避免无效触发:

useEffect(() => {
  // 用filename作为唯一标识判断是否真的有变更,也可根据业务需要替换为深比较
  if (file?.filename !== document?.filename) {
    setDocument(file);
  }
}, [file, setDocument, document]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 12:45:03