是什么原因导致该组件检测到其道具的变化



在下面的最小示例中,父组件具有data属性并将data.value传递给子组件。我很难理解更新策略到底发生了什么:

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(现在,当点击按钮时,我认为会发生以下情况:

  • 应用程序的handleButtonClick()被执行,data-状态现在指向一个新对象。因此,应用程序的第一个useEffect(检查data(触发。

  • 然而,data.value仍然包含相同的引用(对MY_DATAVALUE(,因此App的第二个useEffect(检查data.value(不会触发。

BUT:儿童的useEffect(检查props(触发器。为什么?根据父母的说法,data.value没有改变(否则第二个useEffect会被触发(。

你能解释一下为什么ChildsuseEffect会触发吗?我怎么知道道具"真的"变了?我需要单独检查所有道具钥匙吗?非常感谢。

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]);

相关内容

  • 没有找到相关文章

最新更新