Reactjs 为什么useEffect钩子不能在依赖项数组中触发对象?

Reactjs 为什么useEffect钩子不能在依赖项数组中触发对象?,reactjs,react-hooks,use-effect,use-state,Reactjs,React Hooks,Use Effect,Use State,在使用钩子时,我注意到一些非常奇怪的事情,我有以下几点: 从React导入React,{useState,useffect}; const[dependency1,setDependency1]=useState{}; const[dependency2,setDependency2]=useState[]; useEffect=>{ console.logdependency 1得到更新; },[dependency1]; useEffect=>{ console.logdependency

在使用钩子时,我注意到一些非常奇怪的事情,我有以下几点:

从React导入React,{useState,useffect}; const[dependency1,setDependency1]=useState{}; const[dependency2,setDependency2]=useState[]; useEffect=>{ console.logdependency 1得到更新; },[dependency1]; useEffect=>{ console.logdependency 2得到更新; },[dependency 2]; setInterval=>{ SetDependency1PreveDep1=>{ const_key=test_+Math.random.toString; 如果prevDep1[\u key]==未定义的prevDep1[\u key]=[]; else prevDep1[key].pushfoo; 返回prevDep1; } setDependency2prevDep2=>[…prevDep2,Math.random]; }, 1000; 出于某种原因,只有带有dependency2的useffect(添加项的数组)会触发,带有dependency1的useffect(添加键的对象)不会触发


为什么会发生这种情况,我如何才能使其正常工作?

您在此处返回一份作业声明:

setDependency1(prevDep1 => prevDep1["test_" + Math.random().toString()] = ["foo"]);
您应该返回一个对象。可能是这样的:

setDependency1(prevDep1 => ({ ...prevDep1, ["test_" + Math.random().toString()]: ["foo"] }));

您将在此处返回分配语句:

setDependency1(prevDep1 => prevDep1["test_" + Math.random().toString()] = ["foo"]);
您应该返回一个对象。可能是这样的:

setDependency1(prevDep1 => ({ ...prevDep1, ["test_" + Math.random().toString()]: ["foo"] }));

React仅在确定依赖项已更改时检查引用相等性,因此,如果旧值和新值通过===检查,则认为它未更改


在第一个依赖项中,您只需向现有对象添加一个键,因此不会更改实际对象。在将旧值分散到新数组中时,第二个依赖项实际上会被完全替换。

React仅在确定依赖项已更改时检查引用相等性,因此如果新旧值通过===检查,则认为它没有更改

setInterval(() => {
    setDependency1(prevDep1 => {
      const _key = "test_" + Math.random().toString();
      return {...prevDep1, [_key]: [...(prevDep1[_key] || []), 'foo']   }
    })
    setDependency2(prevDep2 => [...prevDep2, Math.random()]);
  }, 1000);
在第一个依赖项中,您只需向现有对象添加一个键,因此不会更改实际对象。在将旧值分散到新数组中时,第二个依赖项实际上被完全替换

setInterval(() => {
    setDependency1(prevDep1 => {
      const _key = "test_" + Math.random().toString();
      return {...prevDep1, [_key]: [...(prevDep1[_key] || []), 'foo']   }
    })
    setDependency2(prevDep2 => [...prevDep2, Math.random()]);
  }, 1000);
状态应该以不变的方式更新


状态应该以不变的方式更新。

但是如果我必须使用if语句呢?删除短返回语法,像使用普通函数一样使用它。e、 g PREVEDEP1=>{如果某个条件{return someValue;}或者{return otherValue;}}不幸也不起作用,请查看我更新的问题..检查@Mordechai的答案。他已经指出了问题所在。相等性检查失败,因为每次都返回相同的对象。您可以尝试用return{…prevedep1}替换return prevedep1,但是如果我必须使用if语句呢?请删除简短的return语法,并像使用普通函数一样使用它。e、 g PREVEDEP1=>{如果某个条件{return someValue;}或者{return otherValue;}}不幸也不起作用,请查看我更新的问题..检查@Mordechai的答案。他已经指出了问题所在。相等性检查失败,因为每次都返回相同的对象。你可以尝试用return{…prevDep1}替换return prevDep1。我更新了我的问题,使它返回了一些东西,但仍然不起作用。最后一段不再有效,但另一点仍然正确。只要旧道具和新道具通过引用相等性检查,它就不会触发更改。我更新了我的问题,因此它返回了一些内容,但仍然不起作用。最后一段不再有效,但另一点仍然正确。只要新旧道具通过引用相等性检查===它就不会触发更改。