gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 14:22:43 27 4
gpt4 key购买 nike

在下面的最小示例中,父组件具有 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.value 仍然包含相同的引用(对 MY_DATAVALUE),因此应用的第二个 useEffect (检查 >data.value) 不会触发。

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

你能向我解释一下为什么 Childs useEffect 会触发`吗?我怎样才能知道 Prop 是否“真的”改变了?我是否必须单独检查所有 Prop key ?谢谢!

最佳答案

如果我们提供的内容不同,

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

const newData = {
value: MY_DATAVALUE
};

setData(newData);

data 现在引用不同的对象,而 value 键引用与之前的值相同的值。

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

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

虽然这不会触发:

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

到目前为止,这就是您在这两点中所解释的内容。

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

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

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

虽然这个钩子(Hook)不会触发:

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

// In Parent...

<Child value={MY_DATAVALUE} />

// In Child...

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

关于javascript - 是什么导致该组件检测到其 props 的变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60377260/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com