是什么导致该组件检测其 props 的变化?

What causes this component to detect changes in its props?

在下面的最小示例中,parent 组件具有 data 属性 并将 data.value 传递给 child。我正在努力了解更新策略到底发生了什么:

const MY_DATAVALUE = {
  a: 1,
  b: 2
};

const DATA = {
  value: MY_DATAVALUE
};

function Child(props) {
  useEffect(() => {
    console.log("child props changed");
  }, [props]);

  return <h1>Child</h1>;
}

export default function App() {
  const [data, setData] = useState(DATA);

  useEffect(() => {
    console.log("data changed");
  }, [data]);

  useEffect(() => {
    console.log("data.value changed");
  }, [data.value]);

  function handleButtonClick() {
    const newData = {
      value: MY_DATAVALUE
    };
    setData(newData);
  }

  return (
    <>
      <button onClick={handleButtonClick}>Button</button>
      <Child value={data.value} />
    </>
  );
}

(见此Codesandbox) 现在,单击按钮时,我认为会发生以下情况:

但是:Child 的 useEffect(检查 props)触发器。这是为什么?根据 parent,data.value 没有改变(否则第二个 useEffect 会被触发)。

你能给我解释一下,为什么 Childs useEffect 会触发吗?我怎么知道道具 "really" 是否改变了?我是否必须单独检查所有 prop-keys? 谢谢!

useEffect 如果我们提供的内容不同,依赖项将触发更改。如果我们传递具有不同值的相同引用,或者如果我们传递不同的引用,就会发生这种情况。

const newData = {
  value: MY_DATAVALUE
};

setData(newData);

data 现在指的是不同的对象,而 value 键指的是与以前的值相同的对象。

这意味着,这个钩子将触发:

useEffect(() => {
  console.log("data changed");
}, [data]);

虽然这不会触发:

useEffect(() => {
  console.log("data.value changed");
}, [data.value]);

到目前为止,这就是您对这两点的解释。

对于子对象,props 对象是每次渲染时的新引用。

因此,这个钩子总是会触发:

useEffect(() => {
  console.log("child props changed");
}, [props]);

虽然这个钩子不会触发:

const MY_DATAVALUE = {
  a: 1,
  b: 2
};

// In Parent...

<Child value={MY_DATAVALUE} />

// In Child...

useEffect(() => {
  console.log("child value changed");
}, [props.value]);