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

子组件挂载调用父组件函数时遇Maximum update depth exceeded错误怎么修复?

解决React组件无限更新深度超限问题

这个错误的核心原因是子组件调用父组件的回调函数后,父组件执行了setState导致子组件重新渲染,而子组件的useEffect又因依赖项变化再次触发回调,形成无限循环。

具体解决方案

方案1:限制回调仅在组件挂载时执行一次

如果你的需求是子组件挂载时检查status并触发一次回调,后续status变化不需要重复触发,可以将useEffect的依赖数组设为空数组,这样它只会在组件首次挂载时执行:

function Light(props: IProps) {
    let { language } = useContext(LangContext);
    let { noResponse, off, onn } = language == Languages.fa ? fa_Pages.node : en_Pages.node;

    let { node: { status, nodeName, icon, roomName, name, serial } } = props;
    let { backgroundColor, callback, clientId } = props;

    useEffect(() => {
        if (!status) {
            let message = `MSG:DAT:${nodeName}-STATUS:STA*END*`;
            let topic = `IHS/${clientId}/${serial}`;

            console.log("callback ", topic, message);
            callback({ topic, message })
        }
    }, []) // 空数组:仅组件挂载时执行一次
}

注意:如果nodeName、clientId、serial这些变量是动态变化的,且需要在挂载时获取最新值,需要将它们加入依赖数组,但同时要确保父组件传递的callback不会因每次渲染重新创建(可以在父组件用useCallback包裹回调函数),避免useEffect意外重复执行。

方案2:用标记避免重复触发回调

如果需要在status变为false时触发回调,但要防止循环,可以用useRef创建一个标记,记录回调是否已经执行过:

import { useRef } from 'react';

function Light(props: IProps) {
    let { language } = useContext(LangContext);
    let { noResponse, off, onn } = language == Languages.fa ? fa_Pages.node : en_Pages.node;

    let { node: { status, nodeName, icon, roomName, name, serial } } = props;
    let { backgroundColor, callback, clientId } = props;
    const hasTriggeredCallback = useRef(false); // 记录是否已触发回调

    useEffect(() => {
        // 仅当status为false且未触发过回调时执行
        if (!status && !hasTriggeredCallback.current) {
            let message = `MSG:DAT:${nodeName}-STATUS:STA*END*`;
            let topic = `IHS/${clientId}/${serial}`;

            console.log("callback ", topic, message);
            callback({ topic, message });
            hasTriggeredCallback.current = true; // 标记为已触发
        }

        // 当status变为true时重置标记,下次status变为false时可再次触发
        if (status) {
            hasTriggeredCallback.current = false;
        }
    }, [status, callback, clientId, nodeName, serial]);
}

方案3:检查父组件回调逻辑

此外要确认父组件中,执行callback后是否会导致status反复在true和false之间切换——如果父组件的setState操作让status再次变为false,就会再次触发子组件的useEffect,形成循环。需要调整父组件的状态更新逻辑,确保不会让status无意义地重复变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 21:35:12