React清理函数疑问:为何useEffect清理执行不符合预期?
问题分析与解决办法
嘿,这个坑我之前刚踩过!你忽略了React useEffect最关键的依赖数组参数,这直接导致了你的预期和实际结果不符。
为什么会出现不符合预期的情况?
当你不给useEffect传递第二个参数(依赖数组)时,React会把这个effect判定为每次组件渲染都需要执行——包括props变化、state更新,甚至父组件重新渲染触发的当前组件渲染。
而且React的执行逻辑是:每次执行新的effect之前,都会先调用上一次effect返回的清理函数。所以当props变化导致组件重新渲染时,流程是这样的:
- 执行上一次effect的清理函数 → 打印
will unmount2 - 执行新的effect回调 → 打印
didmount
这就导致你看到will unmount2被多次打印,而不是只在组件销毁时执行一次。
怎么修正到符合你的预期?
如果你想让effect只在组件挂载时执行一次,清理函数只在组件卸载时执行一次,只需要给useEffect加上一个空的依赖数组[]:
useEffect(() => { console.log('didmount') return () => { console.log('will unmount2') } }, []) // 空数组告诉React:这个effect只依赖空的变量集合,也就是只在挂载和卸载时执行
额外提醒
如果你的effect回调里用到了props或者state中的变量,那空数组就不适用了——你需要把用到的变量都放进依赖数组里,否则会出现闭包捕获旧值的问题。但如果你的需求就是挂载和卸载各执行一次,空数组就是完全正确的写法。
内容的提问来源于stack exchange,提问作者ventro_art
相关产品推荐
相关产品推荐

