diff --git a/src/components/practice/InputArea.tsx b/src/components/practice/InputArea.tsx index 0d8ab19..15b5af8 100644 --- a/src/components/practice/InputArea.tsx +++ b/src/components/practice/InputArea.tsx @@ -37,13 +37,23 @@ export function InputArea({ } }, [userInput]) - const handleCharInput = (index: number, value: string) => { + const handleCharInput = ( + index: number, + e: React.ChangeEvent + ) => { if (inputLocked) return + const value = e.target.value + const nativeIsComposing = + typeof (e.nativeEvent as InputEvent).isComposing === 'boolean' + ? (e.nativeEvent as InputEvent).isComposing + : false + const composing = isComposing || nativeIsComposing + const newInput = [...userInput] // 输入法组合期间,只更新当前输入框的值,不做任何跳转 - if (isComposing) { + if (composing) { newInput[index] = value onInputChange(newInput) return @@ -125,7 +135,7 @@ export function InputArea({ ref={(el) => (inputRefs.current[index] = el)} type="text" value={char} - onChange={(e) => handleCharInput(index, e.target.value)} + onChange={(e) => handleCharInput(index, e)} onKeyDown={(e) => handleKeyDown(index, e)} onCompositionStart={onCompositionStart} onCompositionEnd={onCompositionEnd} diff --git a/src/pages/ProcessPracticePage.tsx b/src/pages/ProcessPracticePage.tsx index 7430f87..9e260d2 100644 --- a/src/pages/ProcessPracticePage.tsx +++ b/src/pages/ProcessPracticePage.tsx @@ -48,6 +48,7 @@ export default function ProcessPracticePage() { const [userInput, setUserInput] = useState([]) const [charStatuses, setCharStatuses] = useState([]) const [isComposing, setIsComposing] = useState(false) + const isComposingRef = useRef(false) const [lastErrorTimestamp, setLastErrorTimestamp] = useState( null ) @@ -198,19 +199,21 @@ export default function ProcessPracticePage() { latestInputRef.current = newInput setUserInput(newInput) - if (isComposing) return + if (isComposingRef.current) return validateInput(newInput) }, - [isComposing, validateInput] + [validateInput] ) // 输入法状态管理 const handleCompositionStart = useCallback(() => { + isComposingRef.current = true setIsComposing(true) }, []) const handleCompositionEnd = useCallback(() => { + isComposingRef.current = false setIsComposing(false) // 输入法确认后,需要将当前输入框中的所有字符分散到后续输入框 requestAnimationFrame(() => {