Javascript 是什么导致该组件检测其道具的变化?
在下面的最小示例中,父组件具有Javascript 是什么导致该组件检测其道具的变化?,javascript,reactjs,react-hooks,use-effect,Javascript,Reactjs,React Hooks,Use Effect,在下面的最小示例中,父组件具有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]); ret
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} />
</>
);
}
const MY_DATAVALUE={
答:1,,
b:2
};
常数数据={
值:我的数据值
};
功能儿童(道具){
useffect(()=>{
console.log(“更改了子道具”);
}[道具];
返回儿童;
}
导出默认函数App(){
const[data,setData]=使用状态(data);
useffect(()=>{
控制台日志(“数据更改”);
},[数据];
useffect(()=>{
console.log(“data.value已更改”);
},[data.value]);
函数handleButtonClick(){
常数newData={
值:我的数据值
};
setData(newData);
}
返回(
按钮
);
}
(见此)
现在,单击按钮时,我认为会发生以下情况:
- 应用程序的
被执行,并且handleButtonClick()
-状态现在指向一个新对象。因此,应用程序的第一个数据
(检查useffect
)触发数据
- 但是
仍然包含相同的引用(指向data.value
),因此应用程序的第二个MY_DATAVALUE
(检查useffect
)不会触发data.value
useffect
(检查props
)触发。为什么呢?根据家长的说法,data.value
没有改变(否则会触发第二个useffect
)
你能给我解释一下,为什么childuseffect
triggers`?我怎样才能知道道具是否“真的”改变了?我需要单独检查所有道具钥匙吗?
谢谢大家!
useffect
如果我们提供的内容不同,依赖项将触发更改。如果我们用不同的值传递相同的引用,或者传递不同的引用,就会发生这种情况
const newData = {
value: MY_DATAVALUE
};
setData(newData);
数据
现在指的是不同的对象,而值
键指的是与上一个值相同的对象
这意味着,此挂钩将触发:
useEffect(() => {
console.log("data changed");
}, [data]);
虽然这不会触发:
useEffect(() => {
console.log("data.value changed");
}, [data.value]);
const MY_DATAVALUE = {
a: 1,
b: 2
};
// In Parent...
<Child value={MY_DATAVALUE} />
// In Child...
useEffect(() => {
console.log("child value changed");
}, [props.value]);
到目前为止,这是你在两个方面所解释的 对于子对象,
props
对象是每个渲染上的新引用
因此,此挂钩将始终触发:
useEffect(() => {
console.log("child props changed");
}, [props]);
虽然此挂钩不会触发:
useEffect(() => {
console.log("data.value changed");
}, [data.value]);
const MY_DATAVALUE = {
a: 1,
b: 2
};
// In Parent...
<Child value={MY_DATAVALUE} />
// In Child...
useEffect(() => {
console.log("child value changed");
}, [props.value]);
const MY_DATAVALUE={
答:1,,
b:2
};
//在父。。。
//在孩子。。。
useffect(()=>{
console.log(“子值已更改”);
},[props.value]);
我认为这是因为App
组件的状态作为道具传递给Child
,而App
组件通过状态更新重新呈现,因此由于没有对对象内容进行“深入”比较,因此也会重新呈现子组件。我认为您需要使用useReducer
进行深度状态对象比较。usemo
和useCallback
检查道具的差异。使用效果会在任何更改时触发,尽管它是相同的数据谢谢您的明确解释。尤其是“道具对象是每次渲染的新参考”这句话,让我明白了!一件小事:“如果我们用不同的值传递相同的引用”意味着我们用不同的原语值传递相同的引用,对吗?@Raphael,不客气!是的,这就是我的意思,对于对象来说,谈论引用和值会让人困惑{}==={}
将返回false,而const a={}
a===a
将返回true;在原语的情况下,正如您所说的123==123
将返回true。