react Hook使用笔记:当useEffect的依赖频繁变化时的优化方案

news/2024/7/15 18:42:29 标签: react.js, javascript, 前端

问题描述:

有时候我们的 effect 可能会使用一些频繁变化的值。而我们可能会忽略依赖列表中的state,但这通常会引起 Bug,例如:

javascript">function MyCounter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const id = setInterval(() => {
      setCount(count + 1); // 这个 effect 依赖于 `count` state变量
    }, 1000);
    return () => clearInterval(id);
  }, []); // 🔴 Bug: `count` 没有被指定为依赖

  return <h1>{count}</h1>;
}

这里传入空的依赖数组 [],意味着该 hook 只在组件挂载时运行一次,并非重新渲染时。但如此会存在问题,在 setInterval 的回调中,count 的值不会发生变化。因为当 effect 执行时,会创建一个闭包,并将 count 的值被保存在该闭包当中,且初值为 0。每隔一秒,回调就会执行 setCount(0 + 1),因此,count 永远不会超过 1。

指定 [count] 作为依赖列表就能修复这个 Bug,但会导致每次改变发生时定时器都被重置。事实上,每个 setInterval 在被清除前(类似于 setTimeout)都会调用一次。但这并不是我们想要的。

解决方案:

要解决这个问题,我们可以使用setState的函数式更新形式。它允许我们指定 state 该如何改变而不用引用当前state:

javascript">function MyCounter() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    const id = setInterval(() => {
      setCount(c => c + 1); // ✅ 在这不依赖于外部的 `count` 变量
    }, 1000);
    return () => clearInterval(id);
  }, []); // ✅ effect 不使用组件作用域中的任何变量

  return <h1>{count}</h1>;
}

此时,setInterval 的回调依旧每秒调用一次,但每次 setCount 内部的回调取到的 count 是最新值(在回调中变量命名为 c)。

在一些更加复杂的场景中(比如一个 state 依赖于另一个 state),可尝试用useReducer Hook 把 state 更新逻辑移到 effect 之外。 


http://www.niftyadmin.cn/n/152453.html

相关文章

人工智能(Pytorch)搭建卷积神经网络实现简单图像分类

本文参加新星计划人工智能(Pytorch)赛道&#xff1a;https://bbs.csdn.net/topics/613989052 目录 一、Pytorch深度学习框架 二、卷积神经网络 三、代码实战 内容&#xff1a; 一、Pytorch深度学习框架 PyTorch是一个开源的深度学习框架&#xff0c;它基于Torch进行了重新…

全国青少年软件编程(Scratch)等级考试一级真题——2021.9

青少年软件编程&#xff08;图形化&#xff09;等级考试试卷&#xff08;一级&#xff09;分数&#xff1a;100.00 题数&#xff1a;37一、单选题&#xff08;共25题&#xff0c;每题2分&#xff0c;共50分&#xff09;1. 如下图所示&#xff0c;小明想要做一个文字逐字出现的动…

信息系统分析与设计——信息系统建设

&#x1f31f;所属专栏&#xff1a;信息系统分析与设计&#x1f414;作者简介&#xff1a;rchjr——五带信管菜只因一枚&#x1f62e;前言&#xff1a;该系列将持续更新信息系统分析与设计课程的相关学习笔记&#xff0c;欢迎和我一样的小白订阅&#xff0c;一起学习共同进步~&…

为你摇一树桃花

【壹】 叶无道与夏诗筠的姻缘一路坎坷&#xff0c;却是命中注定的&#xff0c;正如吴暖月所说“在我这个局外人看来他们之间真的有种宿命和轮回的感觉”&#xff0c;也可以拿叶子老妈所说的“孽缘”来形容。 两人相识还是夏诗筠九岁的时候,那时有了叶无道为夏诗筠摇桃花的故事…

Git仓库迁移

背景 由于公司原来的gitee地址需要改完新的gitlab仓库&#xff0c;大量的服务模块已再本地进行开发&#xff0c;且存在大量分支进行维护&#xff0c;迁移要求历史提交记录也得同步&#xff0c;需要简单快捷一并完成各服务已经分支迁移。 一、在新的目标git中创建新代码仓 新…

高新技术企业认定 国家高新技术企业复审指南

​平时所说的高新技术企业的认定复审&#xff0c;实际上就是重新认定。第一次高企通过三年后需要重新认定。因此&#xff0c;所谓复审相当于重新做出新的认定&#xff0c;其程序和要求也和新的高新认定一致。 根据《高新技术企业认定管理办法》&#xff0c;国家高新技术企业有…

190. 颠倒二进制位

题目描述 颠倒给定的 32 位无符号整数的二进制位。 提示&#xff1a; 请注意&#xff0c;在某些语言&#xff08;如 Java&#xff09;中&#xff0c;没有无符号整数类型。在这种情况下&#xff0c;输入和输出都将被指定为有符号整数类型&#xff0c;并且不应影响您的实现&am…

elasticsearch高级查询api

yml配置 #es配置 spring:elasticsearch:rest:uris: 192.168.16.188:9200添加依赖 <dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId> </dependency>使用编程的形式…