react useEffect 在组件挂载时运行了两次
2024-06-17
45
在开发环境下,如果开启严格模式,React 会在实际运行 setup 之前额外运行一次 setup 和 cleanup。
这是一个压力测试,用于验证 Effect 的逻辑是否正确实现。如果出现可见问题,则 cleanup 函数缺少某些逻辑。cleanup 函数应该停止或撤消 setup 函数所做的任何操作。一般来说,用户不应该能够区分 setup 被调用一次(如在生产环境中)和调用 setup → cleanup → setup 序列(如在开发环境中)。
Effect 在每次重新渲染后都运行
首先,请检查是否忘记指定依赖项数组:
useEffect(() => {
// ...
}); // 没有依赖项数组:每次重新渲染后重新运行!
如果你已经指定了依赖项数组,你的 Effect 仍循环地重新运行,那是因为你的某个依赖项在每次重新渲染时都是不同的。
你可以通过手动打印依赖项到控制台来调试此问题:
useEffect(() => {
// ..
}, [serverUrl, roomId]);
console.log([serverUrl, roomId]);
然后,你可以右键单击控制台中来自不同重新渲染的数组,并都选择“存储为全局变量”。假设第一个被保存为 temp1,第二个被保存为 temp2,然后你可以使用浏览器控制台来检查两个数组中的每个依赖项是否相同:
Object.is(temp1[0], temp2[0]); // 第一个依赖项在数组之间是否相同?
Object.is(temp1[1], temp2[1]); // 第二个依赖项在数组之间是否相同?
Object.is(temp1[2], temp2[2]); // ... 以此类推检查每个依赖项 ...
当你发现某个依赖项在每次重新渲染都不同时,通常可以通过以下方式之一来解决:
在 Effect 中根据先前 state 更新 state 删除不必要的对象依赖项 删除不必要的函数依赖项 从 Effect 读取最新的 props 和 state作为最后的手段(如果这些方法没有帮助),使用 useMemo 或 useCallback(用于函数)包装其创建。
更新于:3个月前赞一波!
相关文章
- React路径不变location.search参数改变不触发useEffect
- 在IIS部署React前端项目
- 自定义事件子组件与父组件通信
- Vue组件插槽的使用
- React Error: Exceeded timeout of 5000 ms for a test. 错误
- Vue组件之动态组件
- React @testing-library UserEvent.paste用法更新到14版本后不生效
- @testing-library/react单元测试getBy queryBy和findBy的区别
- Vue 组件介绍及使用
- Vue组件的data必须是一个函数、单个根元素、局部组件
- React获取url参数的几种方法
- Vue 父子组件通信传值(子组件中使用父组件中的数据)
- react监听路由变化
- Vue和React怎么选?
- react hooks获取url参数
- react单元测试模拟点击浏览器返回按钮时触发popstate事件
- react基础面试问题
- react获取url参数 忽略参数名大小写
- react获取url参数不区分大小写
- 如何在React中使用路由?
文章评论
全部评论