【解决方案】< antd input > onChange事件

4,030 阅读1分钟

1. 问题描述

  1. 大部分人都是使用拼音输入;
  2. antdinput组件在输入中文时会导致输入的拼音也会触发inputonChange事件;
  3. 会导致没必要的渲染和一些错误的触发

2. 核心思想

3. 解决方案

import { Input, InputProps } from 'antd';
import React, { ChangeEvent, useState, CompositionEvent, useEffect } from 'react';

interface ICommonInputProps extends Omit<InputProps, 'onChange'> {
  onChange?: (value: string) => void;
}

const CommonInput = (props: ICommonInputProps) => {
  const { value, onChange, ...restProps } = props;

  const [curValue, setValue] = useState(value);
  const [isComposing, setComposing] = useState(false); // 是否正在输入法录入中
  // 是否是谷歌浏览器
  const isChrome = navigator.userAgent.indexOf('WebKit') > -1;

  useEffect(() => {
    setValue(value);
  }, [value]);

  const handleCompositionStart = () => {
    setComposing(true);
  };

  const handleCompositionEnd = (event: CompositionEvent<HTMLInputElement>) => {
    setComposing(false);
    // 谷歌浏览器onChange事件在handleCompositionEnd之前触发
    if (isChrome) {
      onChange?.(event.currentTarget.value);
    }
  };

  const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
    // 没有采用输入法的值
    const rawValue = event.target.value;
    setValue(rawValue);
    if (!isComposing) {
      onChange?.(rawValue);
    }
  };

  return (
    <Input
      {...restProps}
      value={curValue}
      onChange={handleChange}
      onCompositionStart={handleCompositionStart}
      onCompositionEnd={handleCompositionEnd}
    />
  );
};

export default React.memo(CommonInput);