当前位置: 首页 > 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…...

Llama-3.2V-11B-cot应用场景:跨境电商多语言商品图信息提取案例

Llama-3.2V-11B-cot应用场景&#xff1a;跨境电商多语言商品图信息提取案例 1. 项目背景与价值 跨境电商平台每天需要处理海量商品图片&#xff0c;传统人工标注方式面临三大痛点&#xff1a; 语言障碍&#xff1a;商品图可能包含多种语言的文字信息效率瓶颈&#xff1a;人工…...

硬件工程师职业发展路径与核心技术解析

硬件工程师的职业发展路径与技术深度探讨1. 行业现状与职业定位1.1 硬件工程师的职责演变现代硬件工程师的职责范围已从传统的电路设计扩展到系统集成、信号完整性分析、EMC设计等多个领域。典型的职责矩阵包括&#xff1a;职责类别传统要求现代扩展要求电路设计原理图绘制、PC…...

保姆级教程:在OrangePi 5 Plus上从SSD启动Ubuntu 22.04,并配置ROS2 Humble环境

OrangePi 5 Plus开发板全栈配置指南&#xff1a;从SSD启动到ROS2 Humble环境搭建 拿到一块OrangePi 5 Plus开发板时&#xff0c;如何快速搭建一个稳定高效的开发环境&#xff1f;本文将手把手带你完成从系统烧录到ROS2环境配置的全过程&#xff0c;特别针对ARM64架构的优化方案…...

FPGA信号调试必备:Quartus中keep、preserve、noprune的正确用法与避坑指南

FPGA信号调试必备&#xff1a;Quartus中keep、preserve、noprune的正确用法与避坑指南 在FPGA开发过程中&#xff0c;信号调试是最令人头疼的环节之一。特别是当你发现仿真时明明存在的关键信号&#xff0c;在综合后却神秘消失时&#xff0c;那种挫败感简直难以言表。作为一名长…...

3月17枚举

package com.fangfa.day05.Enum;public class EnurmerDemo1 {public static void main(String[] args) {//为什么其他类里可以类名.对象名 因为这个对象名被static修饰了//若不修饰不行System.out.println(Season.SPRING);} } class Season{/*** Description* author Mao Ree…...

告别卡顿!用UE5关卡流送(Level Streaming)优化你的开放世界游戏性能

告别卡顿&#xff01;用UE5关卡流送&#xff08;Level Streaming&#xff09;优化你的开放世界游戏性能 当玩家在广袤的开放世界中自由探索时&#xff0c;没有什么比突然的加载卡顿或帧率骤降更能破坏沉浸感了。作为UE5开发者&#xff0c;我们常常面临一个两难选择&#xff1a;…...

C语言诞生秘史:从被逼出到首个编译器的坎坷之路

C语言&#xff0c;是运用C语言自身来进行编译的&#xff0c;这一情况听起来好似那鸡生蛋、蛋生鸡这般&#xff0c;但早年贝尔实验室的那帮人实则真就把它给做成了&#xff0c;并非依靠魔法做到的&#xff0c;而是被逼迫到那种程度才达成的。被逼出来的语言临近1970年的时候 &am…...

陶瓷淬火时“啪“一声裂开的瞬间,背后藏着相场模型里的连续损伤演化。今天咱们用Matlab玩个热应力场+相场断裂的耦合计算,看看脆性材料怎么被温度场玩坏

matlab相场热力耦合断裂问题&#xff0c;陶瓷淬火算例&#xff0c;paraview可视化先上主菜——相场控制方程。核心是温度场T与相场d的相爱相杀&#xff1a; % 热传导方程残差计算 function R_T calc_heat_residual(T, d, dt)kappa 1e-5; % 热扩散系数grad_T gradient(T);R_T…...

ESP32+BC260Y+L76K开发板实战:NB-IoT户外定位数据上传MQTT全流程(附避坑指南)

ESP32BC260YL76K开发板实战&#xff1a;NB-IoT户外定位数据上传MQTT全流程&#xff08;附避坑指南&#xff09; 在物联网应用快速发展的今天&#xff0c;户外定位数据的采集与传输已成为智慧农业、资产追踪、环境监测等领域的核心需求。ESP32作为一款高性价比的Wi-Fi/蓝牙双模芯…...

ABC系统实战指南:革新数字电路设计的逻辑综合与形式验证技术突破

ABC系统实战指南&#xff1a;革新数字电路设计的逻辑综合与形式验证技术突破 【免费下载链接】abc ABC: System for Sequential Logic Synthesis and Formal Verification 项目地址: https://gitcode.com/gh_mirrors/ab/abc 在现代集成电路设计流程中&#xff0c;工程师…...