In front-end development, it is no problem to trigger the update of the content of the input box by listening to theonInput
event, but if the input content is in Chinese, something likezhong'wen'nei'rong
will appear Alternative content.
The impact of this kind of content is generally not great, but when some time-consuming operations need to be performed on the input content, this impact has to be considered, for example, the content needs to be rendered complex, sent in real time through the network, etc. etc. scene.
The solution to this problem requires the combined input events provided by the browser. To put it simply, when inputting Chinese, Japanese, Korean and other texts that contain the "word selection" link, two additional events will be triggered compositionStart
and compositionEnd
, monitor and process these two events event, you can wait without triggering the onInput
event when the user has not finished selecting words:
From the MDN documentation: compositionstart
If you only need to process combined input, use compositionEnd
instead of onInput
, but users occasionally need to input English and numbers, these inputs will not trigger compositionEnd
.
Therefore, we need to enter the waiting state when compositionStart
, and all the waiting states onInput
will not be processed. When inputting English and letters, onInput
is processed normally.
There are many ways to mark the wait state, such as useRef
.
import { useRef } from "react";
export function ChineseInput(params){
const { onInput = () => {} } = params;
const lockRef = useRef(false);
// 进入组合输入状态
const handleStart = () => {
lockRef.current = true
};
const handleInput = event => {
// 处于组合输入状态,不予处理
if(lockRef.current) return;
// 非组合输入状态,触发 onInput
onInput(event);
};
// 选字结束,触发 onInput
const handleEnd = event => {
lockRef.current = false;
onInput(event);
};
return (
<input
{...params}
onCompositionEnd={handleEnd}
onCompositionStart={handleStart}
onInput={handleInput}
/>
)
}
Of course, it can be changed to a higher-order function, so that there is no need to write a component separately for textArea
, but the common input tags are only these two, so there is no need to reuse them.
The compatibility of these two events is not bad:
Computers that are still using these old browsers can basically be ignored. If they insist on compatibility, I am afraid that they can only be replaced by appropriately modified anti-shake or throttling functions.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。