【IOS】input 输入中文拼音频繁触发 onChange 事件的问题

1,679 阅读1分钟

问题描述

使用 IOS 原生输入法输入中文,会出现频繁触发 onChange 事件,如下图

origin_img_v2_726bdee6-a40b-418a-a46c-d6e28abec6cg.jpg

原因是,IOS 原生输入法输入中文被识别成了字母输入,导致每个拼音都触发了 onchange 事件

触发条件

  1. 使用IOS中文输入法输入
  2. 直接处理输入值(如正则等格式化操作)

受控组件与非受控组件

html 输入框在直接使用 IOS 中文输入法输入情况下,且在非受控组件的情况下,即在 onChange 事件中直接处理输入值(如正则等格式化操作,会导致上述问题)

非受控组件在这里可以理解为 input 的输入值、状态等不受框架、脚本的控制,而由自身控制。

解决方法

借助 input 的 onCompositionStartonCompositionEnd 事件,判断是否在拼写中,在拼写结束后再更新 input 值

以下是一个在输入时消除空格的例子,常用在账号或密码输入时消除空格

import React, { useState, FC, useRef } from 'react'

const Input: FC = props => {
  const [value, setValue] = useState(defaultValue || '')
  const isInputting = useRef<boolean>(false)

  const onChange = (inputCurrentValue: string) => {
    if (isInputting.current) {
      return
    }
    setValue(inputCurrentValue)
  }

  return (
    <input
      value={value}
      onCompositionStart={() => {
        isInputting.current = true
      }}
      onCompositionEnd={() => {
        isInputting.current = false
        inputChange(value)
      }}
      onChange={e =>
        onChange(
          /\s$/.test(e.target.value)
            ? e.target.value.replace(/\s+/g, '')
            : e.target.value,
        )
      }
    />
  )
}