我可以在 useEffect 的依赖数组中使用动态属性吗?
Can I use dynamic properties in dependency array for useEffect?
所以我有一个关于 useEffect 依赖项的问题
这是来自反应文档:
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]
。如果我们看一下前面的示例,这两个结果都会为真,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"
does React keep track of the ... value, or ... the reference ?
React 不真的'keep track'其中任何一个。它只检查 与上一次调用 的差异,而忽略其他所有内容。
Can I use dynamic properties as a dependency?
是的,你可以(因为它们不像你想象的那样'dynamic')。
So what's the correct approach?
最好少考虑任何正在发生的反应魔法,但是
- 理解组件是一个函数,相信 React 会在必要时调用它并且
- 从一个普通的Javascript角度考虑其中使用的变量(属性和状态)。
那么你的'dynamic properties'就变成了'constant variables during one function call'。无论哪些变量动态变化,如何变化,总是上次一个值,现在一个值。
解释:
这里重要的 'trick' 是,组件只是一个 javascript 函数,调用方式类似于 'whenever anything might have changed',因此 useEffect()
也被调用(因为 useEffect() 只是组件内部的函数调用)。
只是传递给useEffect的回调函数并不总是被调用。
useEffect
不 渲染组件,useEffect
被调用 当 组件被调用时,并且然后只调用给它的函数,或者不调用,这取决于 dependencies 数组中的任何值是否与上次调用 useEffect() 时的值不同。
React 可能 重新渲染组件,如果在给 useEffect 的函数中对状态或其他东西做了任何更改(任何让 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 没有改变!)
MyComponent()
又被调用了
(这是一个新的函数调用。所有的常量都没有了!只有 React 在后台存储一些状态。)
useState()
被调用,结果存储在一个新常量selectedEmployee
. 中
useEffect()
被调用,并根据 selectedEmployee
.
的先前和当前值决定是否调用其回调
如果没有调用回调并且没有其他任何更改,您可能根本不会注意到发生了什么。
<MyClickableComponent ... />
被渲染。
所以我有一个关于 useEffect 依赖项的问题
这是来自反应文档:
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]
。如果我们看一下前面的示例,这两个结果都会为真,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"
does React keep track of the ... value, or ... the reference ?
React 不真的'keep track'其中任何一个。它只检查 与上一次调用 的差异,而忽略其他所有内容。
Can I use dynamic properties as a dependency?
是的,你可以(因为它们不像你想象的那样'dynamic')。
So what's the correct approach?
最好少考虑任何正在发生的反应魔法,但是
- 理解组件是一个函数,相信 React 会在必要时调用它并且
- 从一个普通的Javascript角度考虑其中使用的变量(属性和状态)。
那么你的'dynamic properties'就变成了'constant variables during one function call'。无论哪些变量动态变化,如何变化,总是上次一个值,现在一个值。
解释:
这里重要的 'trick' 是,组件只是一个 javascript 函数,调用方式类似于 'whenever anything might have changed',因此 useEffect()
也被调用(因为 useEffect() 只是组件内部的函数调用)。
只是传递给useEffect的回调函数并不总是被调用。
useEffect
不 渲染组件,useEffect
被调用 当 组件被调用时,并且然后只调用给它的函数,或者不调用,这取决于 dependencies 数组中的任何值是否与上次调用 useEffect() 时的值不同。
React 可能 重新渲染组件,如果在给 useEffect 的函数中对状态或其他东西做了任何更改(任何让 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 没有改变!) MyComponent()
又被调用了
(这是一个新的函数调用。所有的常量都没有了!只有 React 在后台存储一些状态。)useState()
被调用,结果存储在一个新常量selectedEmployee
. 中
useEffect()
被调用,并根据selectedEmployee
.
的先前和当前值决定是否调用其回调 如果没有调用回调并且没有其他任何更改,您可能根本不会注意到发生了什么。<MyClickableComponent ... />
被渲染。