当前位置: 首页 > news >正文

React hooks的闭包陷阱

react hooks 陷阱

  • hooks必须放在函数顶层, 不能在条件分支和方法内

1、useState陷阱

异步陷阱

function Index() {const [count, setCount] = useState(0)function add(){setCount( count + 1 )console.log(count);  // 0}return (<div><span>{count}</span><button @click=()=>{ add() }> + </button></div>)
}

点击一次按钮,发现页面是更新了,但是console还是上一次的值

【解决方法】:

  • 所以我们不能修改后,把值去拿去其他操作 (应该拿 count+1)
  • 可以通过 promise 来 .then 获取 最新 👇
function Index() {const [count, setCount] = useState(0)function add(){new Promise((resolve) => {setCount((count) => {resolve(count + 1)return count + 1})}).then((res) => {// 下一步操作console.log(res)})}return (<div><span>{count}</span><button onClick={add}> ++ </button></div>)
}

合并陷阱,只执行最后一个

function Index() {const [count, setCount] = useState(0)function add(){setCount( count + 1 )setCount( count + 2 )setCount( count + 3 ) // 只执行这个}return (<div><span>{count}</span><button onClick={add}> ++ </button></div>)
}

此时 只执行了 最后一个 setCount , 导致数据部分逻辑未执行
如果出现这种 判断条件多次 操作 useState 怎么解决 👇

function add(){let num = count;if(...) { num += 1; }if(...) { num += 2; }if(...) { num += 3; }setCount( num );}

那就不写多个setCount

再看个例子:

function Index() {const [count, setCount] = useState(100);function add(){// 合并setCount( count + 1 )setCount( count + 1 )console.log(1, count) // 100// 传入函数,不会合并setCount( count => count + 1 )setCount( count => count + 3 )console.log(2, count) // 100// 点击一次后 count显示为105}return (<div><span>{count}</span> <button onClick={() => add() } > + </button></div>)
}

2、useEffect 陷阱

过期闭包

function Index() {const [count, setCount] = useState(0)useEffect(()=>{setInterval(() => {   console.log(`Count: ${count}`)  }, 1000)}, [])return (<div><span>{count}</span><button onClick=()=>{ setCount(count+1) }> + </button></div>)
}

默认就会运行 每隔1s打印0
点击按钮,count有更新,但是console一直是0
说明此时的 useEffect 中的 count ,还是取的 过期的值

react特点,每次更新都会重新执行这个函数,每次就+1, 是另外一个函数了,不是原来这个函数
但是setInterval的count永远是第一个函数里面的,形成了闭包

【解决方法】:
需要,添加依赖项 count ,
并且每次更新,添加计时器,结束改变计时器

function Index() {const [count, setCount] = useState(0);useEffect(()=>{const time = setInterval(() => {   console.log(`Count: ${count}`)  }, 1000)return () => { clearInterval(time) } // 关键  清除上一次的setInterval }, [count])return (<div><span>{count}</span><button @click=()=>{ setCount(count+1) }> + </button></div>)
}

3、useCallback 陷阱

useCallback 本来拿来优化性能,当依赖变化不用重新注册该函数
使用不当 也会出现一定的问题

获取父组件的值,不是最新

function Parent() {let [count, setCount] = useState(0);return (<div><button onClick={() => setCount(count+1)}> +1 </button>// 子组件<Child count={count} /></div>)
}function Child(props){let log = useCallback(() => {  console.log(props.count)  }, [])return (<div>count: {props.count}<button onClick={() => log()}> 打印 </button></div>)
}

此时我们在 父组件点击 增加按钮
子组件的 count 发生改变 ,我们在点击打印按钮,发现count 一直是0
说明useCallback 依赖为【】数组,取到count 已经过期了

【解决方法】
方法1 :等于没有优化 (依赖更新,useCallback重写一次)

  let log = useCallback(() => {  console.log(props.count)  }, [props.count])

方法2 :将获取 count 的方法 创建到父组件,子组件调用父组件方法

function Parent() {let [count, setCount] = useState(0);let log = useCallback(() => {  console.log(count)  }, [])return (<div><button onClick={() => setCount(count+1)}> +1 </button>// 子组件<Child count={count} log={log} /></div>)
}function Child(props){return (<div>count: {props.count}<button onClick={() => props.log()}> 打印 </button></div>)
}

相关文章:

React hooks的闭包陷阱

react hooks 陷阱 hooks必须放在函数顶层&#xff0c; 不能在条件分支和方法内 1、useState陷阱 异步陷阱 function Index() {const [count, setCount] useState(0)function add(){setCount( count 1 )console.log(count); // 0}return (<div><span>{count}…...

20.3 OpenSSL 对称AES加解密算法

AES算法是一种对称加密算法&#xff0c;全称为高级加密标准&#xff08;Advanced Encryption Standard&#xff09;。它是一种分组密码&#xff0c;以128比特为一个分组进行加密&#xff0c;其密钥长度可以是128比特、192比特或256比特&#xff0c;因此可以提供不同等级的安全性…...

一文详解防御DDoS攻击的几大有效办法

伴随互联网的飞速发展&#xff0c;网络安全问题变得越来越突出&#xff0c;其中最常见的就是DDoS攻击&#xff0c;也就是分布式拒绝服务攻击。DDoS攻击者利用计算机或其他设备的协作&#xff0c;以发送大量请求的方式导致目标超负荷&#xff0c;导致不能正常运转或“宕机”。以…...

Python二级 每周练习题24

练习一: 体重比较器 要求: 请编程实现如下功能: (1)程序开始运行时&#xff0c;提醒用户输入三个人的名字和体重 (可以分开输入&#xff0c;每次输入名字或者体重) (2) 程序自动比较&#xff0c;找出最重的一个人的名字和体重输出 的格式不限&#xff0c;但是要有最重人的姓名…...

MySQL - Buffer Pool

Buffer Pool 主要用于缓存数据库表的数据页&#xff0c;以提高数据库的读取性能&#xff1a; 缓存数据页&#xff1a;Buffer Pool 是 MySQL 中用于缓存数据页的内存区域。数据页通常包含数据库表的数据&#xff0c;如行记录等。当查询或读取数据时&#xff0c;MySQL会首先查看…...

c++ 拆分函数返回值和参数类型

在c中&#xff0c;函数参数类型和返回值类型通常是一个比较明确的信息&#xff0c;好像确实无需在这个上面费周折。然而&#xff0c;硬编码数据类型会让代码复用性下降&#xff0c;如果能够通过某种方式自动获取函数参数和返回值类型&#xff0c;对于代码的可复用性&#xff0c…...

Ubuntu 23.10安装TeXlive并安装CTEX中文支持

连接上互联网&#xff0c;打开SHELL命令行界面&#xff0c; 1. sudo apt install texlive texstudio texlive-lang-chinese 就可以安装好了。texlive-lang-chinese 是TEXLIVE对CTEX中文的支持。 2. Tex源文件必须采用UTF-8编码格式&#xff0c;编译器采用xelatex。这样对中文…...

SpringBoot中CommandLineRunner详解(含源码)

文章目录 前言实例导入库application.yamlRunnerSpringBootCommandLineRunnerApplication执行结果 先后顺序示例OrderRunner1OrderRunner2执行结果 通常用法加载初始化数据示例 启动后打印应用信息示例 启动异步任务示例 接口健康检查示例 外部服务调用示例 参数校验示例 动态设…...

通信基础(一):数据传输基础

一、波特率与比特率关系 比特率(信息传输速率、信息速率):指单位时间内在信道上传 送的数据量(即比特数),单位为比特每秒 (bit/s), 简记为b/s或bps。 波特率与比特率有如下换算关系&#xff1a; bitbaud *log 2(N) 其中&#xff0c; N是码元总类数。 特别注意&#xff…...

故障诊断模型 | Maltab实现BiLSTM双向长短期记忆神经网络故障诊断

文章目录 效果一览文章概述模型描述源码设计参考资料效果一览 文章概述 故障诊断模型 | Maltab实现BiLSTM双向长短期记忆神经网络故障诊断 模型描述 利用各种检查和测试方法,发现系统和设备是否存在故障的过程是故障检测;而进一步确定故障所在大致部位的过程是故障定位。故障…...

物联网和互联网医院小程序:如何实现医疗设备的远程监测和管理?

物联网&#xff08;IoT&#xff09;技术的发展为医疗设备的远程监测和管理提供了巨大的机会。结合互联网医院小程序&#xff0c;我们可以实现对医疗设备的远程访问、监控和管理&#xff0c;从而提高医疗服务的质量和效率。本文将介绍如何实现医疗设备的远程监测和管理&#xff…...

sharepoint2016-2019升级到sharepoint订阅版

一、升级前准备&#xff1a; 要建立新的sharepoint订阅版环境&#xff0c;需求如下&#xff1a; 1.单服务器硬件需求CPU 4核&#xff0c;内存24G以上&#xff0c;硬盘300G&#xff08;根据要迁移的数量来扩容大小等&#xff09;&#xff1b; 2.操作系统需要windows server 20…...

CTFHub | MySQL流量、Redis流量、MongoDB流量的WriteUp

文章目录 MySQL流量题目题解 Redis流量题目题解 MongoDB流量题目题解 数据库类流量题需要用到Wireshark截取数据包&#xff0c;然后进行分析。 WireShark是非常流行的网络封包分析工具&#xff0c;可以截取各种网络数据包&#xff0c;并显示数据包详细信息。常用于开发测试过程…...

NSS刷题 js前端修改 os.path.join漏洞

打算刷一遍nssweb题&#xff08;任重道远&#xff09; 前面很简单 都是签到题 这里主要记录一下没想到的题目 [GDOUCTF 2023]hate eat snake js前端修改 这里 是对js的处理 有弹窗 说明可能存在 alert 我们去看看js 这里进行了判断 如果 getScore>-0x1e9* 我们结合上面…...

ArcGIS Maps SDK for JS:隐藏地图边框

文章目录 1 问题描述2 解决方案 1 问题描述 近期&#xff0c;将ArcGIS Api for JS v4.16更新到了ArcGIS Maps SDK for JS v4.27&#xff0c;原本去除地图的css代码失效了。 v4.26及以前版本 &#xff0c;需要用.esri-view-surface--inset-outline:focus::after 控制边框属性。…...

带你秒懂MySQL!! 一万字详细知识点和基础操作 欢迎评论区怼我 (三)

表操作 创建 # 创建表结构 create table user(id int comment ID,唯一标志,username varchar(20) comment 用户名,name varchar(10) comment 姓名,age int comment 年龄,gender char(1) comment 性别 ) comment 用户表; 约束 非空约束限制该字段值不为nullnot null唯一约束保证…...

kubeadmin部署k8s1.27.4

kubeadmin部署k8s1.27.4 环境介绍 IP主机名资源配置系统版本192.168.117.170k8s-master2c2g200gCentos7.9192.168.117.171k8s-node12c2g200gCentos7.9192.168.117.172k8s-node22c2g200gCentos7.9 编辑本地解析且修改主机名 三台主机都要做 vim /etc/hosts配置主机名 mast…...

【Aurix Tricore】HighTec启动代码crt0-tc37x.c分析笔记

1. 前言 crt0是hightec 在其toolchain的gcc库中实现启动startup功能的核心代码。 HighTec已为tc3xx设置了一些默认的启动行为。在此启动过程中,目标被初始化并设置为其默认值。启动文件的代码在进入main()函数之前执行。之后,执行main()函数的构造函数。 编译器附带的启动…...

Linux高级命令(扩展)

一、find命令 1、find命令作用 在Linux操作系统中&#xff0c;find命令主要用于进行文件的搜索。 2、基本语法 # find 搜索路径 [选项 选项的值] ... 选项说明&#xff1a; -name &#xff1a;根据文件的名称搜索文件&#xff0c;支持*通配符 -type &#xff1a;f代表普通文…...

LLM在text2sql上的应用 | 京东云技术团队

一、前言&#xff1a; 目前&#xff0c;大模型的一个热门应用方向text2sql它可以帮助用户快速生成想要查询的SQL语句。那对于用户来说&#xff0c;大部分简单的sql都是正确的&#xff0c;但对于一些复杂逻辑来说&#xff0c;需要用户在产出SQL的基础上进行简单修改&#xff0c…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

Webpack性能优化:构建速度与体积优化策略

一、构建速度优化 1、​​升级Webpack和Node.js​​ ​​优化效果​​&#xff1a;Webpack 4比Webpack 3构建时间降低60%-98%。​​原因​​&#xff1a; V8引擎优化&#xff08;for of替代forEach、Map/Set替代Object&#xff09;。默认使用更快的md4哈希算法。AST直接从Loa…...

【学习笔记】erase 删除顺序迭代器后迭代器失效的解决方案

目录 使用 erase 返回值继续迭代使用索引进行遍历 我们知道类似 vector 的顺序迭代器被删除后&#xff0c;迭代器会失效&#xff0c;因为顺序迭代器在内存中是连续存储的&#xff0c;元素删除后&#xff0c;后续元素会前移。 但一些场景中&#xff0c;我们又需要在执行删除操作…...

毫米波雷达基础理论(3D+4D)

3D、4D毫米波雷达基础知识及厂商选型 PreView : https://mp.weixin.qq.com/s/bQkju4r6med7I3TBGJI_bQ 1. FMCW毫米波雷达基础知识 主要参考博文&#xff1a; 一文入门汽车毫米波雷达基本原理 &#xff1a;https://mp.weixin.qq.com/s/_EN7A5lKcz2Eh8dLnjE19w 毫米波雷达基础…...