Tab
또는 Enter
로 다음 인풋을 추가하는 방식입니다.IME
조합 상태) Tab
또는 Enter
를 누르면,
useFieldArray 오류 의심
처음에는 React Hook Form의 useFieldArray
사용 방식이 잘못됐다고 생각해, append
시 ID 중복 문제, setValue
강제 초기화 등 여러 시도를 했으나 실패하였습니다.
한글 입력 시 IME(입력기) 조합중 이벤트
문제를 검색해보다가 Composition Event(onCompositionStart
, onCompositionEnd
)가 있다는 사실을 알게 되었습니다. 한글은 자모음 조합이 완전히 끝나기 전에(글자가 확정되기 전) onKeyDown
이 먼저 호출되고 Enter/
Tab 입력을 처리해버려서 “조합 중인 문자가 그대로 넘어가” 버리는 것이 문제의 원인이었습니다.
조합 중임을 판단해 무시하기
onCompositionStart
/onCompositionEnd
에서 isComposing
을 true/false로 저장하기로 하였습니다.onKeyDown
에서 isComposing이 true면(조합 중이면) Tab, Enter 처리를 막았습니다.function ExampleComponent() {
const [isComposing, setIsComposing] = useState(false);
// 한글 IME 조합 시작/종료
// onCompositionStart / onCompositionEnd 이벤트 핸들러
const handleComposition = (e: React.CompositionEvent<HTMLInputElement>) => {
if (e.type === 'compositionstart') {
setIsComposing(true);
} else if (e.type === 'compositionend') {
setIsComposing(false);
}
};
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
// 한글 조합 중이라면 조합 완료 후에만 Enter/Tab 동작 처리
if ((e.nativeEvent as any).isComposing || isComposing) return;
// ... 나머지 로직
};
return (
<input
onKeyDown={handleKeyDown}
onCompositionStart={handleComposition}
onCompositionEnd={handleComposition}
/>
)
}
한글/영문 상관없이, 입력 중에 특정 조건으로 새 인풋을 생성해도 마지막 조합 중인 글자가 새 인풋에 남지 않게 할 수 있었습니다. 이를 통해 이전처럼 임의로 setValue 등을 통해 문자열을 강제로 지우는 편법 로직을 제거할 수 있었습니다.
IME(입력기) 특성
에러 발생의 범위
React, React Hook Form 문제 X
CompositionEvent의 활용