是什么导致该组件检测其 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)
现在,单击按钮时,我认为会发生以下情况:
应用程序的 handleButtonClick()
被执行并且 data
-state 现在指的是一个新的 object。因此 App 的第一个 useEffect
(检查 data
)触发器。
但是 data.value
仍然包含相同的引用(对 MY_DATAVALUE
),因此 App 的第二个 useEffect
(检查 data.value
)不会触发.
但是: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]);
在下面的最小示例中,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) 现在,单击按钮时,我认为会发生以下情况:
应用程序的
handleButtonClick()
被执行并且data
-state 现在指的是一个新的 object。因此 App 的第一个useEffect
(检查data
)触发器。但是
data.value
仍然包含相同的引用(对MY_DATAVALUE
),因此 App 的第二个useEffect
(检查data.value
)不会触发.
但是: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]);