useInputMetehod
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { useRef, useState } from "react"; | |
export interface InputMethodProps { | |
value: string; | |
onChange(value: string): void; | |
} | |
/** | |
* This hook handles composition events to prevent onChange | |
* from being called while the user is typing Chinese pinyin. | |
* And it will call onChange when the user finishes typing pinyin. | |
* @param props | |
* @returns | |
*/ | |
export function useInputMethod<E extends HTMLInputElement | HTMLTextAreaElement>(props: InputMethodProps) { | |
const inputRef = useRef<HTMLInputElement>(null); | |
const onChange = props.onChange; | |
// set to true if (Chines) input method is composing | |
const composingRef = useRef(false); | |
const [value, setValue] = useState<string>(props.value); | |
// The composingValue will be the Pinyin that user is typing, | |
const [composingValue, setComposingValue] = useState<string>(''); | |
const innerValue = composingRef.current ? composingValue : value ?? ''; | |
function handleCompositionStart() { | |
composingRef.current = true; | |
} | |
function handleCompositionEnd(e: React.CompositionEvent<E>) { | |
if (composingRef.current) { | |
composingRef.current = false; | |
handleChange(inputRef.current?.value!, e); | |
} | |
} | |
function handleChange(value: string, e: React.ChangeEvent<E> | React.CompositionEvent<E>) { | |
const newStr = inputRef.current?.value ?? ''; | |
setComposingValue(newStr); | |
// 当中文输入的时候,不触发onChange事件,触发setComposingValue只是为了让输入框同步你输入的text | |
if (!composingRef.current) { | |
// 中文输入完毕,此时触发onChange | |
setValue(newStr); | |
onChange && onChange(newStr); | |
} | |
} | |
return { | |
ref: inputRef, | |
value: innerValue, | |
onCompositionStart: handleCompositionStart, | |
onCompositionEnd: handleCompositionEnd, | |
onChange: handleChange | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment