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

Next.js中解决useEffect触发的Maximum update depth exceeded警告

问题诊断

控制台抛出Maximum update depth exceeded警告的核心原因是组件进入了无限重渲染死循环,代码中存在三处典型错误写法:

  • ListContainer组件内的useEffect没有传入依赖数组,按照React默认规则,组件每次渲染完成后都会执行该effect回调。而回调中调用了setHTML更新本地状态,状态更新会触发组件重新渲染,渲染完成后又会再次执行effect,形成闭环死循环,最终触发更新深度超限的警告。
  • 父子组件的数组状态更新全部直接修改了原state引用:父组件addItem直接对原数组执行push操作、子组件delItem直接对原数组执行splice操作。React对引用类型的状态变化检测依赖引用地址变更,直接修改原内容不仅会导致状态更新判断失效,还会引发不可预期的渲染bug。
  • 存在冗余的反模式状态设计:既不需要把待渲染的JSX结构存在state中,也不需要额外把props传入的items同步为本地state。React本身是状态驱动视图的框架,渲染逻辑直接在组件返回阶段执行即可,手动存储JSX到state是完全不符合React设计思路的写法。
修复代码

父组件 componentCreator 修复

修正状态更新逻辑,每次更新数组时返回全新的数组引用,不直接修改原state:

import { useState } from "react";
import AppLayout from "../components/AppLayout";
import ListContainer from "../components/ListContainer";

export default function componentCreator(){
    const [item,setItem] = useState([])   

    /* add item to container */
    function addItem(){
        // 通过展开运算符创建新数组,不直接修改原item引用
        const newItem = [
            ...item,
            {
                produto: 'Skol 350ml',
                preco: '1200,00',
                quantidade: 'cx c/ 15 unidades'
            }
        ]
        setItem(newItem)
    }

    return (
        <AppLayout>
            <ListContainer items={item} setItems={setItem}/>
            <div className="productcardbuttonshow" onClick={() => addItem()}>ADICIONAR</div>
        </AppLayout>
    )
}

子组件 ListContainer 修复

删除冗余状态和导致死循环的useEffect,直接基于props生成渲染内容,删除操作同样返回新数组引用:

export default function ListContainer(props){
    /* remove item from container */
    function delItem(id){
        // 通过filter生成新数组,不直接splice修改原数组
        const newItemList = props.items.filter((_, index) => index !== id)
        props.setItems(newItemList)
    }

    // 直接基于props生成列表JSX,数据变化时React会自动重渲染更新视图
    const itemHTML = props.items.map((itemmap,id) => {
        return (
            <div key={id} onClick={() => delItem(id)} className="itemProposta">
                {itemmap.produto} - {itemmap.quantidade} - R$ {itemmap.preco}
            </div>
        )
    })

    return (
        <>
        {itemHTML}
        </>
    )
}

注意:原代码中用来“刷新html容器”的useEffect完全是多余的,React会在props/state变化时自动触发重渲染,不需要手动监听数据变化再强制更新视图。

useEffect 执行机制说明

useEffect的执行时机完全由第二个参数(依赖数组)决定:

  • 不传第二个参数:组件每次渲染完成后都会执行effect回调
  • 传空数组[]:仅在组件首次挂载完成后执行一次
  • 传带依赖项的数组[dep1, dep2]:首次挂载时执行一次,后续只有当数组内任意依赖项的引用发生变化时,才会再次执行effect

内容的提问来源于stack exchange,提问作者Gilberto S. Rocha

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 06:45:41