提问者:小点点

超出最大更新深度的反应警告


这是与我的问题最接近的问题的后续问题:

无限循环效应

我正在创造一个小的反应。学习js应用程序库。我收到这个警告:

超过最大更新深度。当组件在useEffect内部调用setState时,可能会发生这种情况,但useEffect要么没有依赖项数组,要么每个渲染中的一个依赖项都会更改。

我得到了一个功能组件,其中有以下代码:

const propertiesMap2 = new Map([  //There is also propertiesMap1 which has the same structure
["TITLE4",
    {
        propertyValues: {
            myProperty10 : "myVal1",
            myProperty11 : "myVal2",
            myProperty12 : "myVal3",                                                            
        },
        isOpen: true
    }
],
["TITLE5",
    {
        propertyValues: {
            myProperty13 : "myVal4",
            myProperty14 : "myVal5",
            myProperty15 : "myVal6",                                                             
        },
        isOpen: true
    }
],
["TITLE6",
    {
        propertyValues:{
            myProperty16 : "myVal7",
            myProperty17 : "myVal8",
            myProperty18 : "myVal9",
        },
        isOpen: true
    }                                                        
]
]);

const [properties, setPropertiesMapFunc] = useState(new Map());
useEffect(()=>
{
    let mapNum = Number(props.match.params.id);
    setPropertiesMapFunc(mapNum === 1 ?propertiesMap1 : propertiesMap2);
}, [properties]);

每次都会选择正确的属性映射,但正如我所说的,我得到了这个错误。如果propertiesMap是常量而没有任何变化,并且properties作为参数传递给setEffect,那么我为什么会得到它,所以我认为只有在发生变化时才会重新渲染。。


共2个答案

匿名用户

因为您正在组件函数内部创建映射对象,所以它们将在每次渲染中重新创建。正因为如此,你的效果将设置一个新的地图作为新的状态,这将反过来触发另一个重新渲染,你的效果将再次被调用,这将导致一个无限的更新循环。

可以将贴图对象的定义移动到组件外部以解决此问题。

匿名用户

properties是一个映射,当在依赖关系数组中传递给useffect时,它将在每次渲染时重新创建,并且在比较时,它将始终不等于自身,因为映射与JS中的其他非基本类型一样,是按引用而不是按值进行比较的。因此,这将导致每次重新渲染时运行useffect中的函数。

您需要将其包装成某种深度比较函数:https://stackoverflow.com/a/54096391/4468021