·1 分钟阅读·
React 输入法 Input 优化
背景
中文输入法触发次数过多或经过状态库异步处理后输入法无法正常使用的问题
原理
使用 composition 事件检测输入法输入
实现
首先动手确认下 compositionStart,compositionEnd,onChange 三者的顺序关系
<input
onCompositionStart={() => {
console.log("start");
}}
onChange={() => {
console.log("change");
}}
onCompositionEnd={() => {
console.log("end");
}}
/>
chrome
safari
firefox
可以看到,顺序都是 start、change、end
结果
- 支持受控
- 无需进行浏览器判断,目前浏览器行为均一致
import { Input, InputProps } from "antd";
import { useRef, useState, forwardRef, useEffect } from "react";
/**
* https://github.com/facebook/react/issues/3926#issuecomment-1200414788
*/
export const InputIME = forwardRef<any, InputProps>((props, ref) => {
const { onChange, value, ...otherProps } = props;
const [inputValue, setInputValue] = useState("");
useEffect(() => {
setInputValue(value as string);
}, [value]);
const onComposition = useRef(false);
return (
<Input
// 其他默认值
placeholder="请输入文本"
autoComplete="off"
{...otherProps}
ref={ref}
value={inputValue}
onCompositionStart={() => {
onComposition.current = true;
}}
onChange={(e) => {
if (onComposition.current) {
setInputValue(e.target.value);
} else {
onChange?.(e);
}
}}
onCompositionEnd={(e) => {
onComposition.current = false;
onChange?.(e);
}}
/>
);
});
参考
- https://github.com/facebook/react/issues/3926#issuecomment-1200414788
- personal-blog/开发遇到的小问题合集/解决使用输入法输入在 React input 框中的问题.md at master · Jacky-Summer/personal-blog
- react-composition-input/src/inputfield.js at master · LeoEatle/react-composition-input