使用带依赖项的 useEffect 钩子时,什么时候触发清理功能?
When is the cleanup function triggered when using useEffect hook with dependencies?
我正在使用 useEffect 来显示 UI 正在加载...但仅在 250 毫秒之后。
它有效......但我真的不明白为什么以及特别是如何以及何时 useEffect 调用返回的函数(清除超时)。
嗯......我不确定这是否完美。有时应该显示 "Loading ..." 消息,但实际上没有。
const [loadingAfterShortTime, setLoadingAfterShortTime] = useState(false);
useEffect(() => {
setLoadingAfterShortTime(bool => false);
if (myDepandanceToTrigTheLoadingWord === true) {
const id = setTimeout(() => {
setLoadingAfterShortTime(bool => true);
}, 250);
return () => {
clearTimeout(id);
};
}
}, [myDepandanceToTrigTheLoadingWord]);
以下是所涉及时间的概要:
useEffect
在初始渲染时调用,只要它依赖的任何值发生变化。一般来说,它会在渲染完成后触发。如果您将其视为基于 class 的组件,则等同于 componentDidMount
方法。
- 从
useEffect
中返回的函数在组件从 UI 中移除或即将重新渲染(以避免内存泄漏)之前被调用。在执行下一个效果之前,始终会清除上一个效果。它保证在任何新渲染之前 运行。等价于 componentWillUnmount
.
示例
让我们假设有一个 useEffect
几乎没有由 props(传递给我们的组件)+ 清理函数组成的依赖项。在第一次渲染时,会发生以下情况:
- 安装组件后,效果主体内的代码将 运行;
- 清理功能保持不变,准备好在组件重新呈现/从屏幕上移除之前运行。
现在让我们假设有什么触发了重新渲染。由于它被列为 useEffect
依赖的东西,效果将重新执行如下:
- 清理函数在渲染完成后执行;
- 在那之后,效果主体中的代码将 运行;
- 再次创建新的清理函数,准备在组件重新呈现之后/或从屏幕上移除之前执行。
@Powell Ye 提供的解释很好,但是有一些错误信息,特别是在谈到重新渲染时(例如,当道具改变时)
考虑一些具有以下内容的简单组件
useEffect( () => {
console.log('Effect is applied')
//some logic
return () => {
console.log('cleaning up')
//cleanup logic
}
})
return (<>
{console.log('rendering...')}
</>)
假设传递的 props 发生了变化,您可能认为它是这样的
- 'cleaning up'
- 新道具
- 'rendering...'
- 'Effect is applied'
然而,实际发生了以下情况
- 新道具
- 'rendering...'
- 'cleaning up'
- 'Effect is applied'
也就是说,清理函数运行 AFTER 新的 render/painting 但 BEFORE 'new' 效果已应用,docs 对此
可能有点模棱两可
the previous effect is cleaned up before executing the next effect
这样做是出于性能原因 => 这样渲染就不会延迟(有时这对我来说也是令人沮丧的)
根据反应文档,
The clean-up function runs before the component is removed from the UI
to prevent memory leaks. Additionally, if a component renders multiple times (as they typically do), the previous effect is cleaned up before executing the next effect.
React will always flush a previous render’s effects before starting a
new update.
根据我对这两个引号的理解,清理在应用效果之后和组件 卸载(从 UI 中删除)之前运行。
我正在使用 useEffect 来显示 UI 正在加载...但仅在 250 毫秒之后。 它有效......但我真的不明白为什么以及特别是如何以及何时 useEffect 调用返回的函数(清除超时)。
嗯......我不确定这是否完美。有时应该显示 "Loading ..." 消息,但实际上没有。
const [loadingAfterShortTime, setLoadingAfterShortTime] = useState(false);
useEffect(() => {
setLoadingAfterShortTime(bool => false);
if (myDepandanceToTrigTheLoadingWord === true) {
const id = setTimeout(() => {
setLoadingAfterShortTime(bool => true);
}, 250);
return () => {
clearTimeout(id);
};
}
}, [myDepandanceToTrigTheLoadingWord]);
以下是所涉及时间的概要:
useEffect
在初始渲染时调用,只要它依赖的任何值发生变化。一般来说,它会在渲染完成后触发。如果您将其视为基于 class 的组件,则等同于componentDidMount
方法。- 从
useEffect
中返回的函数在组件从 UI 中移除或即将重新渲染(以避免内存泄漏)之前被调用。在执行下一个效果之前,始终会清除上一个效果。它保证在任何新渲染之前 运行。等价于componentWillUnmount
.
示例
让我们假设有一个 useEffect
几乎没有由 props(传递给我们的组件)+ 清理函数组成的依赖项。在第一次渲染时,会发生以下情况:
- 安装组件后,效果主体内的代码将 运行;
- 清理功能保持不变,准备好在组件重新呈现/从屏幕上移除之前运行。
现在让我们假设有什么触发了重新渲染。由于它被列为 useEffect
依赖的东西,效果将重新执行如下:
- 清理函数在渲染完成后执行;
- 在那之后,效果主体中的代码将 运行;
- 再次创建新的清理函数,准备在组件重新呈现之后/或从屏幕上移除之前执行。
@Powell Ye 提供的解释很好,但是有一些错误信息,特别是在谈到重新渲染时(例如,当道具改变时)
考虑一些具有以下内容的简单组件
useEffect( () => {
console.log('Effect is applied')
//some logic
return () => {
console.log('cleaning up')
//cleanup logic
}
})
return (<>
{console.log('rendering...')}
</>)
假设传递的 props 发生了变化,您可能认为它是这样的
- 'cleaning up'
- 新道具
- 'rendering...'
- 'Effect is applied'
然而,实际发生了以下情况
- 新道具
- 'rendering...'
- 'cleaning up'
- 'Effect is applied'
也就是说,清理函数运行 AFTER 新的 render/painting 但 BEFORE 'new' 效果已应用,docs 对此
可能有点模棱两可the previous effect is cleaned up before executing the next effect
这样做是出于性能原因 => 这样渲染就不会延迟(有时这对我来说也是令人沮丧的)
根据反应文档,
The clean-up function runs before the component is removed from the UI to prevent memory leaks. Additionally, if a component renders multiple times (as they typically do), the previous effect is cleaned up before executing the next effect.
React will always flush a previous render’s effects before starting a new update.
根据我对这两个引号的理解,清理在应用效果之后和组件 卸载(从 UI 中删除)之前运行。