所以我有一个关于使用效果依赖性的问题
这是来自react文档:
useEffect(() => {
document.title = `You clicked ${count} times`;
}, [count]); // Only re-run the effect if count changes
这到底意味着什么,React跟踪count
变量及其值,并在值发生变化时做出反应,还是React跟踪数组中的第一个元素及其值。
我的意思是什么?让我解释更多。因此,如果我们有像这样的[name]
作为依赖项。在评估时,数组可能会产生['Bob']
或['Steve']
。很明显,这是一个更改,useEffect将重新提交组件。但它是如何检查的呢?
它是跟踪name
还是跟踪dependencyArray[0]
。如果我们看一下前面的例子,这两个结果都将为true,name
和first element
都将其值从'Bob'
更改为'Steve'
。但它实际上是如何工作的呢?
目前在我的代码中,我使用的是类似于[employees[selectedEmployee].name]
的东西,其中selectedEmployee
是UI上可以点击的东西,它变成了"Bob"或"Steve">
例如:
const employees = {
Bob: {
name: 'Bob'
},
Steve: {
name: 'Steve'
}
}
这意味着,最终,当进行评估时,依赖数组仍将以['Bob']
->['Steve']
产生,如果React正在评估dependencyArray[0]
,那么它显然发生了变化,组件应该重新提交,但如果它跟踪引用,那么我将完全更改引用,这可能会导致问题。
那么,正确的方法是什么呢?我可以使用像employees[selectedEmployee].name
这样的动态属性作为依赖项吗?
count
是一个值,而不是引用。
这只是一个很好的旧Javascript,没有什么花哨的:
const myArray = [ count ]; // new array containing the value of variable 'count'
const myFunction = () => {
document.title = `You clicked ${count} times`;
}
useEffect(
myFunction,
myArray
);
// Means actually:
// "Run this function if any value in the array
// is different to what it was last time this useEffect() was called"
React是否跟踪。。。值,或者。。。参考?
React并没有真正"跟踪"其中的任何一个。它只检查与前一个调用的差异,而忽略其他所有内容。
我可以使用动态属性作为依赖项吗?
是的,你可以(因为它们不像你想象的那样"动态"(。
那么正确的方法是什么?
最好少考虑任何正在发生的反应魔法,但
- 理解组件是一个函数,并相信React在必要时调用它
- 从一个简单的Javascript角度来考虑它内部使用的变量(属性和状态(
然后您的"动态属性">在一个函数调用期间变成的"常量变量">。无论哪些变量动态变化,如何变化,上次总是一个值,现在是一个值。
解释:
这里重要的"技巧"是,组件只是一个javascript函数,它的调用方式类似于"任何事情都可能发生变化">,因此也会调用useEffect()
(因为useEffect((只是组件内部的函数调用(
并非总是只调用传递给useEffect的回调函数。
useEffect
不渲染组件,useEffect
在调用组件时被调用,然后只调用给定给它的函数,或者不调用,这取决于依赖项数组中的任何值是否与上次调用useEffect((时的值不同。
如果在给定给useEffect的函数中,对状态或其他东西进行了任何更改(任何使React认为它必须重新提交的东西(,React可能会重新提交组件,但这是状态更改的结果,无论它来自哪里,而不是因为useEffect调用。
示例:
const MyComponent = (props) => {
// I'm assigning many const here to show we are dealing with local constants.
// Usually you would use this form (using array destructuring):
// const [ selectedEmployee, setSelectedEmployee ] = useState( someInitialValue );
const myStateValueAndSetter = useState( 'Bob' );
const selectedEmployee = myStateValueAndSetter[0];
const setSelectedEmployee = myStateValueAndSetter[1];
const employees = {
Bob: { name: 'Bob' },
Steve: { name: 'Steve' }
};
const currentName = employees[ selectedEmployee ].name;
useEffect(() => {
document.title = 'current name: ' + currentName;
}, [ currentName ]);
return <MyClickableComponent onClick={( newValue ) => {
setSelectedEmployee( newValue )
}}>;
};
- 点击
MyClickableComponent
调用当前的setSelectedEmployee( newValue )
函数
(常数selectedEmployee不变!( - CCD_ 23被再次调用
(这是一个新的函数调用。所有的常量都不见了!只有React在后台存储一些状态。( - 调用
useState()
,结果存储在新的常数selectedEmployee
中 - 调用
useEffect()
,并根据selectedEmployee
的前一个和当前值决定是否应调用其回调
如果没有调用回调,并且没有更改任何其他内容,则您可能根本没有注意到发生了任何事情 - 对CCD_ 28进行渲染