Skip to content

Instantly share code, notes, and snippets.

@aztack
Created January 2, 2023 12:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aztack/c447a0236ed00c68a70257f06971b6b5 to your computer and use it in GitHub Desktop.
Save aztack/c447a0236ed00c68a70257f06971b6b5 to your computer and use it in GitHub Desktop.
useInputMetehod
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