자동완성 기능을 구현하던 중 추천 키워드로 이동 시 기존 입력한 검색어의 마지막 글자가 포함되어 출력되는 문제가 발생했다.
테스트를 해보니 크롬 브라우저에서 한글을 사용하는 경우만 해당 문제가 존재했다.
검색해 보니 한글 입력 시 입력 중인 글자 아래 검은 밑줄이 생기는데 해당 밑줄이 있는 상황에서 키보드 이벤트 발생 시 이벤트핸들러가 두 번 호출 되는 문제가 존재했다.
한글의 경우 자음과 모음의 조합으로 한 음절이 만들어지는 조합 문자이기 때문에 글자가 조합 중인지, 조합이 끝난 상태인지를 알 수 없기 때문이다.
이로 인해 키보드 이벤트에는 isComposing 이라는 입력 문자가 조합 문자인지 아닌지를 boolean값으로 반환하는 프로퍼티가 있었다.
chrome 브라우저 사용 시 keydown 이벤트 핸들러 내부에서 console로 찍어보면 이벤트가 두 번 발생하는 것을 알 수 있다.
참고로 firefox로 확인 시 isComposing의 값은 false로 이벤트가 한 번만 발생한다.
그럼 이제 문제가 isComposing 때문임을 알게 되었다.
오잉? isComposing을 사용해서 문제 해결해야지 했는데 이벤트 객체에 isComposing 속성이 없었다.
리액트의 이벤트가 합성 이벤트(SyntheticEvent)임은 알고 있었지만 실질적으로 처음 체감해 봤다.
리액트의 공식 문서에서 봤던 기억이 있어 공식 문서를 보니 떡하니 "브라우저의 고유 이벤트가 필요하다면 nativeEvent 어트리뷰트를 참조하세요." 라는 문구가 있었다.
navtiveEvent 어트리뷰트를 사용해 브라우저의 고유 키보드 이벤트에 접근하여 isComposing 프로퍼티를 사용하여 문제를 해결했다.
const handleKeyDown = (event: React.KeyboardEvent) => {
if (event.nativeEvent.isComposing) return;
...
};