我在下面的 React 功能组件中有以下 useEffects。我想确保当更新 showComponentProp 时,第一个 useEffect 在运行第二个 useEffect 之前更新状态。
我知道 useEffect 挂钩按照它们在组件主体中出现的顺序运行,但是,由于它们包含 setState 函数,我不能 100% 确定其行为。我不希望 useEffect 挂钩中的两个 setState 函数之间存在竞争条件。
有人可以澄清调用 useEffects 的确切顺序以及在这种情况下何时重新渲染组件吗?例如,是否调用了第一个效果,当更新 isVisible 状态时,组件是否会在调用第二个效果之前重新渲染?在这种情况下,两个效果将在重新渲染后再次运行,或者仅运行第二个效果,因为之前调用了第一个效果。
任何参考资料将不胜感激,因为我找不到解释这一点的资源。
const [isVisible, setIsVisible] = useState(showComponentProp);
useEffect(() => {
setIsVisible(showComponentProp);
}, [showComponentProp]);
useEffect(() => {
if (showComponentProp && timerProp) {
const timeout = setTimeout(() => setIsVisible(false), timerProp);
return () => clearTimeout(timeout);
}
}, [showComponentProp, timerProp]);
我想确保当
更新时, 第一个showComponentProp
在第二个 useEffect 之前更新状态 运行。useEffect
第一个
useEffect
钩子的回调肯定会在调用第二个isVisible
钩子之前enqueue更新
useEffect
状态。
我知道
钩子按照它们出现的顺序运行 然而,在组件主体中,因为它们包含 setState 函数, 我不能 100% 确定这种行为。我不想举行比赛useEffect
钩子中两个 setState 函数之间的条件。useEffect
所有 React hooks 被称为每个渲染周期,按照它们定义的顺序。如果
showComponentProp
发生变化,那么由于它包含在 both useEffect
钩子的依赖数组中,它将按照定义的顺序触发 both useEffect
钩子的回调。
有人可以澄清一下 useEffects 的确切顺序吗 在这种情况下,当组件被重新渲染时被调用。为了 例如,是调用的第一个效果,当
状态时 更新后,组件是否在第二个效果之前重新渲染 叫?在这种情况下,这两种效果都会在 重新渲染,或者只是调用第一个效果时的第二个效果 以前。isVisible
useEffect
钩子回调。isVisible
状态更新排入队列以更新到当前 showComponentProp
值。showComponentProp
和 timerProp
值,如果两者都为 true,则进入 if 块并实例化超时以将另一个 isVisible
状态更新排队为 false,并返回 useEffect
钩子清理功能。timerProp
毫秒后过期,并调用回调将另一个 isVisible
状态更新排队为 false,并触发另一个组件重新渲染,例如回到上面的步骤 1。在任何情况下,每个渲染周期都会调用两个
useEffect
钩子,并且仅当依赖项发生变化时才会调用回调。
但是,我怀疑您可以在一个
useEffect
钩子中完成这一切,这可能会让理解逻辑和流程更容易一些。
const [isVisible, setIsVisible] = useState(showComponentProp);
// Run effect when either showComponentProp or timerProp update
useEffect(() => {
// Only instantiate timeout when we've both truthy
// showComponentProp and timerProp values
if (showComponentProp && timerProp) {
// Enqueue isVisible state update "now"
setIsVisible(true);
// Enqueue timeout to enqueue isVisible state update "later"
const timeout = setTimeout(() => setIsVisible(false), timerProp);
return () => clearTimeout(timeout);
}
}, [showComponentProp, timerProp]);