react: input 输入框 中文onChange事件异常问题& 对input输入进行防抖处理

React 笔记② 验证 阅读详情
AI摘要

文章讲述了在React应用中,当用户使用中文输入法时,onChange事件会因未确认输入就触发的问题。通过利用onCompositionStart、onCompositionUpdate和onCompositionEnd事件,可以判断中文输入状态,避免在输入过程中触发搜索。同时,结合防抖(debounce)函数,可以在中文输入结束后再进行搜索操作,优化用户体验。

当我们使用Input时,我们可能会遇到一个问题,比如需要对用户输入的内容进行搜索时,当用户处于中文输入时,明明没有对内容进行确认,为什么会触发了onChange事件呢?

比如以下场景,中文一边输入另外一边onChange事件就已经被触发了,这样显然是不符合我们的需求的。无论我们对change事件如何做防抖和节流,当用户处于中文输入还没进行确认时,搜索请求就已经发送了。

const NewInput = () => {
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    console.log(e.target.value);
  };

  return <input onChange={handleChange} />;
};

export default NewInput;

那有什么方法进行解决吗?

答案肯定是有的,不然这篇文章就不会写了。

首先,我们要知道input的事件有很多, 这里我们需要用到的方法是 onCompositionStart、onCompositionUpdate以及onCompositionEnd。这三个事件就可以让浏览器判断你的中文输入状态,分别代表着开始输入、正在输入中(输入更新)以及结束输入。
const NewInput = () => {
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    // console.log(e.target.value);
  };

  const Composition = (e: React.CompositionEvent<HTMLInputElement>) => {
    console.log(e.type);
  };

  return (
    <input
      onChange={handleChange}
      onCompositionStart={Composition}
      onCompositionEnd={Composition}
      onCompositionUpdate={Composition}
    />
  );
};

export default NewInput;

接下来,事情就要解决了,对input的onChange事件增加一个判断,当中文输入结束时才会触发搜索操作。

import { useRef } from 'react';
const NewInput = () => {
  // 增加一个状态,记录中文输入状态
  const compositionRef = useRef<boolean>(false);
  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (!compositionRef.current) {
      console.log(e.target.value);
    }
  };

  const Composition = (e: React.CompositionEvent<HTMLInputElement>) => {
    if (e.type === 'compositionend') {
      compositionRef.current = false;
      handleChange(e);
    } else {
      compositionRef.current = true;
    }
  };

  return (
    <input
      onChange={handleChange}
      onCompositionStart={Composition}
      onCompositionEnd={Composition}
      onCompositionUpdate={Composition}
    />
  );
};

export default NewInput;

中文输入触发onChange异常的情况就算解决了。


既然问题解决了,那就再加个防抖节流操作吧。毕竟,都看到这里了,需求一步到位不是更好吗?
// 封装的具有解决中文输入异常问题的Input组件
import React, { useEffect, useRef } from 'react';

// props类型
interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
  value?: any;
  onChange?: (e: any) => void;
}

export default (props: InputProps) => {
  const { value, onChange, ...setProps } = props;
  // 增加一个ref记录输入框的值,继承父组件的value
  const inputRef = useRef<HTMLInputElement>(null);
  const compositionRef = useRef<boolean>(false);

  useEffect(() => {
    if (inputRef.current) {
      // 接受父组件传来的value
      inputRef.current.value = value || '';
    }
  }, [value]);

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (!compositionRef.current) {
      // 执行父组件的change事件
      onChange && onChange(e);
    }
  };

  const Composition = (e: React.CompositionEvent<HTMLInputElement>) => {
    if (e.type === 'compositionend') {
      compositionRef.current = false;
      // 执行父组件的change事件
      onChange && onChange(e);
    } else {
      compositionRef.current = true;
    }
  };
  return (
    <input
      ref={inputRef}
      onChange={handleChange}
      onCompositionStart={Composition}
      onCompositionEnd={Composition}
      onCompositionUpdate={Composition}
      {...setProps}
    />
  );
};
// 父组件
import React, { useCallback, useState } from 'react';
import { createRoot } from 'react-dom/client';
import debounce from 'lodash-es/debounce';
import NewInput from './demo';

const App = () => {
  const [value, setValue] = useState('');
  const handleChange = (e) => {
    setValue(e.target.value);
    debounceSearch(e.target.value);
  };

  // 搜索操作进行防抖处理
  const debounceSearch = useCallback(
    debounce((e: string) => {
      console.log(e);
      //  doSearch(e)
    }, 800),
    []
  );

  return <NewInput value={value} onChange={handleChange} />;
};

createRoot(document.getElementById('container')).render(<App />);

每天进步一点点,成长足迹看得见。

react+ts 获取Input框中的值,并赋值给其他参数 需要处理在输入框没有值,且当删除最后一个数字后,Input输入框中的值就会自动变为0。需要判断当输入框的值为空字符串时,将其转换为0。且添加一个onBlur事件处理函数,当输入框失去焦点时,检查输入框的值是否为空字符串,如果是,则将其转换为0。 阅读详情

相关推荐

【避坑指“难”】React+Ant-Design实现输入框限制字数的动态改变

onChange={(evevnt) =&gt; {setTextValue(evevnt.target.value)}} &lt;span className="remian_words"&gt;{300 - textValue.length}&lt;/span&gt;

椰卤工程师的个人博客 2056

react之onChange事件

如何获取输入框的值是react中必须面对的问题,目前比较好的方式与两种,一种是使用ref,而另一种是使用onChange事件,它通过事件对象的方式获取输入值。 具体使用方式如下:import React,{ Component } from "react";import { render } from "react-dom"; class Main extends Component{ c

程序员老李|前阿里技术专家,10 年前端。 做免费办公工具:图片压缩、PDF、Markdown、在线简历,全在浏览器本地处理。 文件不上传,不用注册。技术栈 Canvas、WebAssembly、Web Worker。 2万+

React实时搜索组件:Axios防抖取消与加载状态精细化实践

实时搜索(Live Search)是B端系统中高频且易出错的交互模式,其本质是客户端对用户连续输入流的异步节流与响应管理。核心原理在于结合防抖(Debounce)控制请求频率、请求取消(AbortController)避免竞态响应、以及多级加载状态(idle/pending/stale)保障UI一致性。技术价值体现在提升用户体验稳定性、降低后端无效负载、规避React并发渲染下的内存泄漏与状态错乱。典型应用场景包括电商后台关键词检索、SaaS管理面板数据过滤、内容聚合平台模糊查询等。本文聚焦React 18

weixin_33898876的博客 383

在react中受控组件input里面onChange传值的问题

在react中,调用事件,如果该事件不是用箭头函数定义的,那就要手动给该事件绑定this,这里不解释原理(this指向问题) 如下一个正常的受控组件input 构造器里面定义的state如下 this.state = { value: ‘’ } 在render中有一个input 通过箭头函数, 2. _handleChange = (event) =&gt; { 3. this.setState(() =&gt; ({ 4. value: event.target.value 5. }))

gaojing1023的博客 7270

RxJS搜索框实战:用响应式流解决防抖、取消请求与状态同步难题

搜索框是典型的异步交互场景,其本质是用户输入意图的连续表达,而非单次事件触发。传统基于addEventListener+setTimeout+AbortController的实现易导致请求堆积、状态错乱和内存泄漏。RxJS通过Observable将输入、防抖、请求、渲染建模为可组合、可中断、可追溯的数据流,以声明式操作符(如debounceTime、switchMap、takeUntil)替代命令式状态管理,天然支持实时搜索、双模式切换、自动资源回收等复杂需求。本文聚焦搜索框这一高频工程组件,详解如何用Rx

aodanchui1057的博客 484

React自定义组件设计:从函数封装到生产级契约

React自定义组件远不止是编写一个返回JSX的函数,其本质是在UI可复用性与逻辑可维护性之间建立清晰边界。它基于React的渲染机制(如reconciliation、key稳定性)、状态管理模型和类型系统原理,解决中大型项目中常见的props透传、无效重渲染、业务逻辑耦合与运行时类型错误等核心问题。技术价值体现在提升组件复用率、保障可访问性(a11y)、支持SSR/CSR一致性,并通过TypeScript接口和测试驱动实现API稳定性。典型应用场景包括搜索输入框、用户卡片、订单状态标签等高频交互模块。本文

weixin_30383279的博客 359

Input输入框的防抖实现方案【deepseek优化版本】

总结,优化后的代码通过useRef和useEffect更好地管理防抖函数的生命周期,避免了内存泄漏和过时闭包问题,同时确保防抖函数总是使用最新的依赖项。对于用户提到的删除卡顿问题,由于输入框的值是即时更新的(通过setInputValue),防抖仅影响onChange回调的触发时机,因此删除操作的响应是流畅的。但这样可能引入新的问题,比如父组件更新propValue时,防抖后的onChange可能覆盖父组件的状态,导致循环更新。不过这是防抖的正常行为,不是异常,但需要确认是否符合需求。

weixin_44542404的博客 1351

RxJS搜索框实战:防抖、竞态控制与状态流设计

搜索框是前端最基础的异步交互场景之一,其本质是处理用户输入事件流与网络响应流的时间关系。传统Promise方案易引发请求竞态、内存泄漏和状态错乱,而RxJS通过Observable抽象事件时间流,以debounceTime、switchMap、distinctUntilChanged等操作符实现声明式控制,将‘人机交互不确定性’转化为可预测的数据流。它不仅优化QPS与首屏响应,更提供面向真实世界的异步状态管理范式——尤其适用于需要防抖、取消旧请求、加载态同步及错误恢复的搜索类功能。

hck341204的专栏 512

react 输入框 input 防抖 debounce

react input debounce 1.需求 当我输入文本时候,对文本进行设置处理 (监控文本更新自动后请求接口) 希望实时的设置输入文字 不使用blur 但是change请求太过于频繁 主要是针对输入框防抖处理 2.处理 使用 lodash 的 debounce 3.遇到的问题 浏览器报异常:Uncaught TypeError: Cannot read property 'value' of null。 如果在react中想异步访问事件属性(如在setTimeout内...

Embrace924的博客 4473

ptrade量化策略之沪深300指数增强

本策略的核心是在沪深300股票池中选股,选择的股票都是市值比较大,业绩比较好的白马股,根据市场相对位置以及基本面因子来选择股票

qq_29301281的博客 1191

设计数据库 ER 图太麻烦?不妨试试这两款工具,自动生成数据库 ER 图!!!

告别手动画图,提高效率~

楼下小黑哥 2万+

看似简单的input框输入竟异常卡顿,记一个日常性能问题的排查思路

我们公司产品主要提供企业项目管理服务,那么自然有配套的desk工单管理系统,用于搜集客户bug以及相关问题反馈。有一天我在测试功能时碰巧发现了一个bug,所以就想着提一个工单记录下方便日后修复。但就在创建工单填写标题时我发现标题输入卡爆了,本想着创建一个bug工单,结果又附带新建了一个性能bug单…下图便是当时问题表现可以看到我只要连续操作,输入框都存在非常明显的卡顿,输入并不流畅,那么本文主要记录此问题的排查思路,以及部分性能排查小技巧,本文开始。...

行星飞行的博客 5331

手机摄影新宠:In-line Hardware EIS如何让你的4K视频稳如鸡头(附实测对比)

本文深入解析了手机摄影中的In-line Hardware EIS(硬件级行内电子图像稳定)技术。通过对比传统软件EIS,阐述了其通过硬件管道实时处理实现极低延迟、减少画面裁切和有效抑制果冻效应的核心优势,并结合4K视频的日夜间实测,展示了该技术如何让手持拍摄的视频“稳如鸡头”,显著提升创作体验与成片质量。

tree的博客 994

简单的input框输入竟然异常卡顿,一个日常性能问题的排查思路

我们公司产品主要提供企业项目管理服务,那么自然有配套的desk工单管理系统,用于搜集客户bug以及相关问题反馈。有一天我在测试功能时碰巧发现了一个bug,所以就想着提一个工单记录下方便日后修复。但就在创建工单填写标题时我发现标题输入卡爆了,本想着创建一个bug工单,结果又附带新建了一个性能bug单....下图便是当时问题表现:可以看到我只要连续操作,输入框都存在非常明显的卡顿,输入并不流畅,那么本文主要记录此问题的排查思路,以及部分性能排查小技巧,本文开始。

1501

2023-11-20 MySQL ARM64 银河麒麟

背景 MySQL是常用数据库,Windows安装比较容易,笔者也有记录。现在国产化系统银河麒麟中安装,不同的是软件安装包不容易下载。一是安装的方式,再一个是MySQL本身的版本,网上很多文档说明其实都是对的,但是为什么那么多都不一样呢?就是MySQL本身的版本差异比较大,这些差异笔者也不是很清楚,但是不要用8和5.7的差异非常大,8即使安装的很顺利,在使用过程也会很多坑,导致我宁愿卸载8,也要重新...

jxmh1991@163.com 810

华为昇腾310P3+deepseek蒸馏版性能调优:FP16精度优化全记录

本文详细介绍了在华为昇腾310P3硬件环境下优化DeepSeek蒸馏版模型FP16精度的关键技术路径。通过分层量化策略、内存分配优化和并行计算配置,显著提升模型推理性能,实现83%的并发处理能力提升,同时保持98.7%的原始模型准确率。

weixin_29074409的博客 347

防抖+中文输入双杀!React搜索框优化实战(附完整hook实现)

本文详细介绍了React搜索框优化中的防抖技术与中文输入法处理方案。通过自定义Hook封装,结合onChange事件与composition事件处理,解决了频繁触发和中文输入异常问题,提供了完整的TypeScript实现和性能优化建议,适用于电商、社交等需要高效搜索的场景。

weixin_29013129的博客 186

置顶必读(1) | 滚雪球学Oracle教程导航帖,带你弯道超车(持续更新中)

什么是数据库管理系统(DBMS),Oracle在行业中的领先地位Oracle数据库的市场竞争与主要应用场景Oracle数据库的核心功能模块与未来技术发展趋势约束的高级应用:主键、唯一性、外键设计与管理表分区、视图、同义词与序列的最佳实践PL/SQL编程的设计哲学,如何高效使用Oracle SQL DeveloperPL/SQL代码调试与优化技巧RAC集群中的高可用性设计,负载均衡与并行查询的配置集群中的缓存一致性管理。

**My Coding Family** 1万+

HTML5文本输入框开发指南:从基础实现到高级优化

文本输入框作为Web开发中最基础的交互组件,其实现原理基于HTML5的表单元素和事件机制。通过input、textarea等原生标签,开发者可以快速构建功能完善的输入界面,这些元素不仅提供了基本的文本接收能力,还内置了类型验证、占位提示等实用功能。在工程实践中,合理的文本输入设计能够显著提升用户体验和数据质量,特别是在用户注册、搜索查询、表单填写等高频场景中。结合JavaScript的事件监听和DOM操作,可以实现实时验证、自动完成、字符计数等增强功能,而CSS的样式定制则确保了视觉一致性。本文聚焦plac

aome1470的博客 361

面向 Cloud Foundry、ABAP On-Prem 与 ABAP Cloud 的 SAP Fiori 开发全景:工具、流程与实战案例

SAP Fiori开发实战:基于BAS的一站式工程化方法 摘要: 本文系统梳理SAP Business Application Studio(BAS)在Fiori开发中的核心能力,提供三种典型后端(Cloud Foundry/ABAP On-Prem/ABAP Cloud)的对接方案。BAS通过预置Fiori Tools套件、MTA部署工具等扩展,支持从模板创建、可视化建模到构建部署的全流程。文章包含CAP+RAP服务对接、ABAP标准应用扩展等实战案例,重点解析注解驱动开发、Adaptation Proj

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 255

小梅哥Xilinx ZYNQ学习笔记2——38译码器

译码器(Decoder)是一种多输入多输出的组合逻辑电路,负责将二进制代码翻译为特定的对象(如逻辑电平等),功能与编码器相反。译码器一般分为通用译码器和数字显示译码器两大类。本设计的是通用译码器。三八译码器,即是 3 种输入状态翻译成 8 种输出状态。1.case开始开始,endcase结束;2.数字声明时,合法的基数格式有 4 中,包括:十进制('d 或 'D),十六进制('h 或 'H),二进制('b 或 'B),八进制('o 或 'O)。数值可指明位宽,也可不指明位宽。

m0_51430584的博客 1636

React密码强度校验实战:zxcvbn懒加载与防抖Hook设计

密码强度校验不是简单的正则匹配,而是基于熵值计算的风险量化过程。其核心原理是通过字典比对、模式识别(如键盘序列、常见单词变形)和马尔可夫链估算破解成本,符合NIST SP 800-63B合规要求。技术价值在于平衡安全性与首屏性能——避免全量加载zxcvbn导致JS阻塞,同时保障实时反馈不干扰用户体验。典型应用场景包括金融SaaS注册页、医疗系统登录表单等需过等保三级的业务系统。本文聚焦React生态下的工程落地,详解zxcvbn异步加载、Web Worker通信、usePasswordStrength自定义

weixin_34210740的博客 349

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

React自动补全组件:构建生产级状态协同系统

Autocomplete(自动补全)是前端交互中典型的状态协同场景,其本质远不止UI渲染——它涉及输入、候选、选中、加载、错误五维状态的强耦合与实时一致性。基于React的实现必须超越useState简单管理,转向useReducer驱动的状态机建模,以应对快速输入、请求取消、键盘导航、网络抖动等真实工程挑战。技术价值在于保障用户意图不丢失、界面反馈不滞后、错误边界可收敛;广泛应用于搜索框、表单联想、代码编辑器提示等场景。本文聚焦React自动补全组件的核心原理与生产就绪实践。

weixin_30568591的博客 605

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Laminar事件系统深度解析:构建交互式UI的完整指南

想要在Scala.js中构建流畅的交互式Web应用吗?**Laminar事件系统**为你提供了强大而优雅的解决方案!🎯 作为一款简单、表达力强且安全的Scala.js UI库,Laminar的事件处理机制是其核心魅力所在,让开发者能够轻松构建响应式用户界面。本文将带你深入了解Laminar事件系统的精髓,掌握构建现代Web应用的关键技能。 ## 🔥 为什么选择Laminar事件系统? La

gitblog_00785的博客 890

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

React+Antd-Mobile遇到的问题记录

6、移动端上传文件限制,使用accept方法时,手机选取文件时会限制默认只能在某个文件下选取,造成不便。5、Popover组件在Mask组件内使用时,点击空白中,弹窗不能自动关闭。解决:在Mask组件的下一级增加一个div,绑定点击事件进行关闭Popover弹窗。2、遇到输入变化请求接口的情况时,一定要增加防抖,防止下个接口请完了,上个接口还没请求完,导致setState赋值无效,视图不更新的问题。7、在进行需要loading操作时,一定要增加不可点击背景的loading,防止用户在等待期间进行其他操作。

web8_zhy的博客 599

React与Unity WebGL双向通信:原理、实现与性能优化

在现代Web开发中,前端框架与3D渲染引擎的深度整合已成为构建复杂可视化应用的关键需求。其核心原理在于建立JavaScript与WebAssembly之间的高效通信桥梁,通过事件驱动与消息传递机制实现数据同步。这一技术方案的核心价值在于能够将React声明式UI的高效状态管理与Unity强大的实时渲染能力相结合,从而突破传统Web应用在交互体验上的局限。在实际工程实践中,开发者常需处理序列化、性能优化与跨平台兼容性等挑战,尤其是在数字孪生、在线教育、互动营销等需要高保真3D展示与复杂业务逻辑并行的应用场景中

蓝色妖姬 1022
上一篇: whistle 一个神奇的前端调试工具(抓包\代理工具)
下一篇: axios配置:错误重试以及设置拦截器,以Csdn为例
wang_9909
博客等级 码龄7年 6514粉丝 109原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值