React 常见的陷阱之(如异步访问事件对象)
文章目录
- 前言
- 1. 异步访问事件对象
- 问题
- 解决方案
- 2. 事件传播的误解
- **问题**
- 解决方案
- **3. 事件监听器未正确卸载**
- **问题**
- **解决方案**
- **4. 动态列表中的事件绑定**
- **问题**
- **解决方案**
- **5. 第三方库与 React 事件冲突**
- **问题**
- **解决方案**
- **6. 表单输入与受控组件**
- **问题**
- **解决方案**
- **7. 事件代理与动态元素**
- **问题**
- **解决方案**
- **最佳实践总结**
前言
在 React 开发中,事件处理(尤其是合成事件)的某些行为可能导致意料之外的错误。以下是常见的陷阱及解决方案:
1. 异步访问事件对象
问题
React 的合成事件对象(SyntheticEvent
)会被重用以提升性能。如果在异步操作(如 setTimeout
、Promise、await
)中直接访问 event
对象的属性,可能会得到 null
或过时值。
const handleClick = (e) => {setTimeout(() => {console.log(e.target); // ❌ 此时 e.target 可能已被重置为 null}, 1000);
};
解决方案
- 提取同步值:在异步操作前提取所需属性。
- 使用
e.persist()
:保留事件对象(但 React 17+ 已优化此问题,但仍需注意兼容性)。
const handleClick = (e) => {const target = e.target; // 提前提取值setTimeout(() => {console.log(target); // ✅}, 1000);// 或显式保留事件对象e.persist();setTimeout(() => {console.log(e.target); // ✅}, 1000);
};
2. 事件传播的误解
问题
e.stopPropagation()
的局限性:
合成事件的e.stopPropagation()
仅阻止 React 组件树的事件冒泡,但不会阻止原生 DOM 事件的传播。- 原生事件与合成事件的执行顺序:
原生事件可能先于合成事件触发(例如捕获阶段绑定的原生事件)。
// React 合成事件
const handleReactClick = (e) => {e.stopPropagation(); // 仅阻止 React 事件传播
};// 原生事件
document.addEventListener("click", (e) => {console.log("原生事件触发"); // 仍然会执行
});
解决方案
- 如需完全阻止事件传播,调用原生事件的
stopImmediatePropagation
:
const handleClick = (e) => {e.nativeEvent.stopImmediatePropagation(); // 阻止原生事件传播
};
3. 事件监听器未正确卸载
问题
在类组件或 useEffect
中绑定的原生事件未及时清理,导致内存泄漏。
useEffect(() => {const handleResize = () => console.log("Resize");window.addEventListener("resize", handleResize);// ❌ 忘记移除监听器return () => {window.removeEventListener("resize", handleResize); // ✅ 必须清理};
}, []);
解决方案
- 在
useEffect
或类组件的componentWillUnmount
中清理事件监听器。
4. 动态列表中的事件绑定
问题
在渲染列表时,直接在 JSX 中使用内联函数(如 onClick={() => handleClick(item)}
)可能导致性能问题或闭包陷阱。
{items.map((item, index) => (<button key={item.id}onClick={() => handleClick(index)} // ❌ 每次渲染生成新函数>{item.name}</button>
))}
解决方案
- 提取事件处理器:通过
data-*
属性传递数据。 - 使用
useCallback
:缓存回调函数。
const handleClick = useCallback((index) => {// 逻辑处理
}, []);{items.map((item, index) => (<button key={item.id}data-index={index}onClick={(e) => handleClick(Number(e.target.dataset.index))} // ✅>{item.name}</button>
))}
5. 第三方库与 React 事件冲突
问题
使用非 React 库(如 jQuery 插件)直接操作 DOM 时,可能因事件冒泡或状态不同步导致冲突。
useEffect(() => {// jQuery 插件绑定点击事件$("#external-button").on("click", () => {console.log("外部库事件"); // 可能干扰 React 状态});
}, []);
解决方案
- 隔离操作:避免直接通过 React 管理第三方库的 DOM。
- 手动同步状态:通过
ref
获取 DOM 节点并绑定事件。
6. 表单输入与受控组件
问题
未正确处理受控组件的 value
和 onChange
,导致输入框无法编辑或状态不同步。
const [value, setValue] = useState("");// ❌ 缺少 onChange 处理
<input value={value} />;// ❌ 错误使用 defaultValue(非受控组件)
<input defaultValue={value} onChange={(e) => setValue(e.target.value)} />;
解决方案
- 严格遵循受控组件模式:
<input value={value} onChange={(e) => setValue(e.target.value)} // ✅
/>;
7. 事件代理与动态元素
问题
在事件委托中,动态生成的子元素可能无法触发事件(如通过 document.addEventListener
绑定)。
// 假设动态添加按钮
document.addEventListener("click", (e) => {if (e.target.tagName === "BUTTON") {console.log("按钮点击"); // 动态添加的按钮无法触发}
});
解决方案
- 使用 React 合成事件而非原生事件委托。
- 若必须使用原生事件,通过事件冒泡到静态父容器处理。
最佳实践总结
- 优先使用合成事件,避免混用原生事件。
- 异步操作中提前提取事件属性或调用
e.persist()
。 - 严格清理原生事件监听器,防止内存泄漏。
- 动态列表使用
key
和高效的事件绑定方式(如data-*
属性)。 - 受控组件确保
value
和onChange
配对使用。
相关文章:
React 常见的陷阱之(如异步访问事件对象)
文章目录 前言1. 异步访问事件对象问题解决方案 2. 事件传播的误解**问题**解决方案 **3. 事件监听器未正确卸载****问题****解决方案** **4. 动态列表中的事件绑定****问题****解决方案** **5. 第三方库与 React 事件冲突****问题****解决方案** **6. 表单输入与受控组件****问…...

Swagger在java的运用
Swagger 是一个广泛使用的工具,用于设计、构建、记录和使用 RESTful Web 服务。它通过提供交互式的 API 文档、客户端 SDK 生成和 API 发现功能,极大地简化了 API 的开发和使用过程。以下是对 Swagger 的详细介绍,包括它的功能、使用场景、如…...

代码随想录算法训练营 Day49 图论Ⅰ 深度优先与广度优先
图论 基础 图的概念 图的概念 概念清单有向图 (a)无向图 (b)有向/无向如图 a 所示每条边有指向如图 b 所示每条边没有箭头指向权值每条边的权值每条边的权值度-有几条边连到该节点 (eg V 2 V_2 V2 度为 3)入度/出度出度:从该节点出发的边个数入度:…...

.NET外挂系列:1. harmony 基本原理和骨架分析
一:背景 1. 讲故事 为什么要开这么一个系列,是因为他可以对 .NET SDK 中的方法进行外挂,这种技术对解决程序的一些疑难杂症特别有用,在.NET高级调试 领域下大显神威,在我的训练营里也是花了一些篇幅来说这个…...

HarmonyOS NEXT端云一体化工程目录结构
视频课程学习报名入口:HarmonyOS NEXT端云一体化开发 端云一体化开发工程由端开发工程(Application)和云开发工程(CloudProgram)两大核心模块构成。 1)端开发工程目录结构 端开发工程主要用于开发应用端侧的业务代码,通用云开发模板的端开发工程目录结构如下图所示: …...

Ajax研究
简介 AJAX Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。 AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。 Ajax 不是一种新的编程语言,而是一种用于创建更好更快以及交互性更强的Web应用…...

学习 Android(十)Fragment的生命周期
简介 Android 的 Fragment 是一个具有自己生命周期的 可重用 UI 组件,能够在运行时灵活地添加、移除和替换,从而支持单 Activity 多界面、动态布局和响应式设计。掌握 Fragment 的生命周期有助于正确地在各个阶段执行初始化、资源绑定、状态保存与释放操…...
flutter 常用组件详细介绍、屏幕适配方案
一、常用组件 1.基础组件 组件说明示例Text显示文本Text(‘Hello Flutter’, style: TextStyle(fontSize: 20))Image显示图片Image.network(‘https://example.com/image.jpg’)Icon显示图标Icon(Icons.home, size: 30, color: Colors.blue)RaisedButton / ElevatedButton按钮…...
Elasticsearch生产环境性能调优指南
#作者:朱雷 文章目录 一、背景二、优化项2.1. 磁盘优化2.2.配置文件优化2.3. jvm 配置2.4. 关闭或禁用 swap2.5. 最大文件描述符2.6. 段合并流量设置2.7. thread_pool相关 三、总结 一、背景 Elasticsearch是基于Lucene的开源分布式搜索与分析引擎,支持…...
野火鲁班猫(arrch64架构debian)从零实现用MobileFaceNet算法进行实时人脸识别(一)conda环境搭建
先安装miniconda wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-aarch64.sh chmod x Miniconda3-latest-Linux-aarch64.sh bash Miniconda3-latest-Linux-aarch64.sh source ~/.bashrc conda --version按照MobileFaceNet的github官方指南,需要…...

RT Thread FinSH(msh)调度逻辑
文章目录 概要FinSH功能FinSH调度逻辑细节小结 概要 RT-Thread(Real-Time Thread)作为一款开源的嵌入式实时操作系统,在嵌入式设备领域得到了广泛应用。 该系统不仅具备强大的任务调度功能,还集成了 FinSH命令行系统,…...
Kotlin 极简小抄 P9 - 数组(数组的创建、数组元素的访问与修改、数组遍历、数组操作、多维数组、数组与可变参数)
Kotlin 概述 Kotlin 由 JetBrains 开发,是一种在 JVM(Java 虚拟机)上运行的静态类型编程语言 Kotlin 旨在提高开发者的编码效率和安全性,同时保持与 Java 的高度互操作性 Kotlin 是 Android 应用开发的首选语言,也可…...
CSS display有几种属性值
在 CSS 中,display 属性是控制元素布局和渲染方式的核心属性之一。它有多种属性值,每个值都决定了元素在文档流中的表现形式。以下是 display 的主要属性值分类及说明: 1. 块级和行内布局 块级元素 (block) 特性:独占一行&…...
【后端】【UV】【Django】 `uv` 管理的项目中搭建一个 Django 项目
🚀 一步步搭建 Django 项目(适用于 uv pyproject.toml 项目结构) 🧱 第 1 步:初始化一个 uv 项目(如果还没建好) uv init django-project # 创建项目,类似npm create vue⚙️ 第 …...

单片机设计_四轴飞行器(STM32)
四轴飞行器(STM32) 想要更多项目私wo!!! 一、系统简介 四轴飞行器是一种通过四个旋翼产生的升力实现飞行的无人机,其核心控制原理基于欧拉角动力学模型。四轴飞行器通过改变四个电机的转速来实现六自由度控制(前后、左右、上下…...
kafka配置SASL_PLAINTEXT简单认证
Kafka ZooKeeper 开启 SASL_PLAINTEXT 认证(PLAIN机制)最全实战教程 💡 本教程将手把手教你如何为 Kafka 配置基于 SASL_PLAINTEXT PLAIN 的用户名密码认证机制,包含 Kafka 与 ZooKeeper 的全部配置,适合入门。 &…...
PostgreSQL简单使用
一、PostgreSQL概念 特点 开源与自由 标准符合性 数据类型丰富 事务与并发 扩展性 安全性 优势 高性能 高可用性 灵活性 社区支持 成本效益 PostgreSQL结构 多层逻辑结构 第一层:实例(xxx.xxx.xxx.xxx…...

【Spring Boot】配置实战指南:Properties与YML的深度对比与最佳实践
目录 1.前言 2.正文 2.1配置文件的格式 2.2properties 2.2.1基础语法 2.2.2value读取配置文件 2.2.3缺点 2.3yml 2.3.1基础语法 2.3.2配置不同数据类型 2.3.3配置读取 2.3.4配置对象和集合 2.3.5优缺点 2.4综合练习:验证码案例 2.4.1分析需求 2.4.2…...

算法优选系列(9.BFS 解决拓扑排序)
目录 拓扑排序简介: 编辑 课程表(medium): 课程表II(medium): 火星词典(hard): 拓扑排序简介: 有向无环图(DAG图) 如上图每条边…...
(1)Java 17/18/19 新特性面试题
Java 17/18/19 新特性面试题 🚀 掌握前沿技术,成为顶尖 Java 工程师 1️⃣ Java 17/18/19 新特性价值点 👉 点击展开题目 Java 17/18/19新特性中,你认为最有价值的是哪些?请结合实际场景说明 密封类(Sealed Classes…...
LAN(局域网)和WAN(广域网)
你的问题非常清晰!我来用一个直观的比喻实际拓扑图帮你彻底理解LAN(局域网)和WAN(广域网)如何协同工作,以及路由器在其中的位置。你可以把整个网络想象成一座城市: 1. 比喻:城市交通…...

【Java高阶面经:微服务篇】7. 1秒响应保障:超时控制如何成为高并发系统的“救火队长”?
一、全链路超时建模:从用户需求到系统分解 1.1 端到端时间预算分配 黄金公式: 用户期望响应时间 = 网络传输时间 + 服务处理时间 + 下游调用时间 + 缓冲时间典型分配策略(以1秒目标为例): 环节时间预算优化目标客户端渲染100ms骨架屏(Skeleton)预渲染边缘节点(CDN)…...

力扣周赛置换环的应用,最少交换次数
置换环的基本概念 置换环是排列组合中的一个概念,用于描述数组元素的重排过程。当我们需要将一个数组转换为另一个数组时,可以把这个转换过程分解为若干个 “环”。每个环代表一组元素的循环交换路径。 举个简单例子 假设原数组 A [3, 2, 1, 4]&…...

大语言模型 12 - 从0开始训练GPT 0.25B参数量 MiniMind2 补充 训练开销 训练步骤 知识蒸馏 LoRA等
写在前面 GPT(Generative Pre-trained Transformer)是目前最广泛应用的大语言模型架构之一,其强大的自然语言理解与生成能力背后,是一个庞大而精细的训练流程。本文将从宏观到微观,系统讲解GPT的训练过程,…...
hgdbv9创建plpython3u插件后无法使用该插件创建函数
文章目录 环境症状问题原因解决方案 环境 系统平台:银河麒麟 (X86_64) 版本:9.0 症状 此问题在如下版本和安装环境出现: 安装包: hgdb-ee-9.0.1.000-build2401091440-28098d3-linux.x86_64.binOS版本&…...

SQLMesh 宏操作符详解:@IF 的条件逻辑与高级应用
SQLMesh 的 IF 宏提供了一种在 SQL 查询中嵌入条件逻辑的方法,允许根据运行时条件动态调整查询结构。本文深入探讨 IF 的语法、使用场景及实际案例,帮助开发者构建更灵活、可维护的 SQL 工作流。 1. IF 宏简介 IF 是 SQLMesh 提供的条件逻辑宏ÿ…...
nt!MiRemovePageByColor函数分析之脱链和刷新颜色表
第0部分:背景 PFN_NUMBER FASTCALL MiRemoveZeroPage ( IN ULONG Color ) { ASSERT (Color < MmSecondaryColors); Page FreePagesByColor[Color].Flink; if (Page ! MM_EMPTY_LIST) { // // Remove the first entry on the zeroe…...

【爬虫】12306自动化购票
上文: 【爬虫】12306查票-CSDN博客 下面是简单的自动化进行抢票,只写到预定票,没有写完登陆, 跳出登陆后与上述代码同理修改即可。 感觉xpath最简单,复制粘贴: 还有很多写法: 官网地址&#…...
不同消息队列保证高可用实现方案
消息队列的高可用性(High Availability, HA)是分布式系统中的核心需求,不同消息队列通过多种技术手段实现高可用。以下是主流消息队列的高可用实现方案及对比: 一、Apache Kafka 副本机制(Replication) 每个…...

【Django系统】Python+Django携程酒店评论情感分析系统
Python Django携程酒店评论情感分析系统 项目概述 这是一个基于 Django 框架开发的酒店评论情感分析系统。系统使用机器学习技术对酒店评论进行情感分析,帮助酒店管理者了解客户反馈,提升服务质量。 主要功能 评论数据导入:支持导入酒店…...