已复制
全屏展示
复制代码

Antdesign中Input.TextArea 的onSearch与onChange无法输入中文问题


· 3 min read

一. 问题复现

在antd组件 antdesign 的文本输入框组件,onChange方法无法识别中文,刚开始我使用了AutoComplete组件,还以为是AutoComplete的问题,最后发现是输入框的问题。官方文档(https://ant.design/components/auto-complete-cn)让使用 onChange ,但是还是不行,也许是我的使用方法不对。复现问题代码:

import {Input} from "antd";

const MyTest = () => {

  const onChange = (event) => {
    console.log(event.target.value)
  }

  return (
    <div style={{margin: 50, width: 300}}>
      <Input.TextArea onChange={onChange}/>
    </div>
  )
}
export default MyTest;

没有任何组件的情况下,就一个div,排查其他的组件的影响,问题复现如下:

Antdesign中Input.TextArea 的onSearch与onChange无法输入中文问题

二. 问题分析

Input.TextAreaonChange 事件在输入中文时可能会出现问题,这是因为在输入中文的过程中,每个键盘按键的敲击都会触发 onChange 事件,而不是在完成整个中文输入后触发。

在输入法输入过程中,每次键盘按键都会被视为一次输入,所以会触发 onChange 事件。这可能会导致输入的中文字符被拆分,或者在输入过程中产生其他不可预期的结果。

解决这个问题的一种方法是使用 onCompositionStartonCompositionEnd 事件来处理中文输入。这两个事件分别在开始和结束输入法输入时触发。我们可以在 onCompositionStart 事件中设置一个标志,然后在 onChange 事件中检查这个标志,如果标志被设置,那么就忽略 onChange 事件。然后在 onCompositionEnd 事件中清除这个标志,并处理输入的文本。

三. 解决问题

我们onCompositionStart 和 onCompositionEnd两个事件,代码如下:

import {Input} from "antd";
import {useState} from "react";

const MyTest = () => {

  const [isComposing, setIsComposing] = useState(false);
  const [inputValue, setInputValue] = useState('');  // 保存输入框的内容

  // 中文输入法问题
  const onChange = (data: any, chineseFinished: boolean = false) => {
    if (chineseFinished) {
      // 中文: data 表示本次输入的中文,加上输入框里面的内容
      const v = inputValue + "" + data
      setInputValue(v)
      console.log("chinese:", v)
    } else if (!isComposing) {
      // 输入英文时直接获取值
      const v = data.target.value
      setInputValue(v)
      console.log("english:", v)
    }
  }

  // 中文输入法问题
  const handleComposition = (event: any) => {
    if (event.type === 'compositionend') {
      setIsComposing(false); // composition is finished
      onChange(event.data, true);  // manually trigger onChange event
    } else {
      setIsComposing(true) // composition is starting
    }
  }

  return (
    <div style={{margin: 50, width: 300}}>
      <Input.TextArea
        onCompositionStart={handleComposition}
        onCompositionEnd={handleComposition}
        onChange={onChange}
      />
    </div>
  )
}
export default MyTest;

当输入中文但是没有回显到输入框时,onChange是做了判断,所以不会打印日志,

输入中文中


回显到输入框后,才打印日志

回显到输入框后,才打印日志

待解决: 如果不是在输入框末尾输入,会出现拼接问题(默认是把输入的中文拼接到最后的)

🔗

文章推荐