웹소켓 라이브러리 socket.io로 실시간 채팅을 구현하던 중 문제가 생겼다.

이렇게 한글로 입력해서 엔터를 치면, 킹받게 마지막 글자만 한 번 더 출력되는 것이다.
뭔 따라쟁이도 아니고...
하지만 영어나 특수문자는 정상적으로 한 번씩만 출력되었다.

왜 한글에서만 이런 현상이 나타나는 걸까?
초반에는 디바운싱으로 해결했으나, 근본적인 문제가 해결된 것 같지 않아서 조금 더 알아보았다.
문제 원인
IME(Input Method Editors) composition
IME는 영어가 아닌 한글, 일본어, 중국어와 같은 언어를 다양한 브라우저에서 지원하도록 언어를 변환시켜주기 위한 OS 단계의 어플리케이션을 말한다. 그러나 IME 과정에서 keydown 이벤트가 발생하면, OS와 브라우저에서 해당 이벤트를 모두 처리하기 때문에 keydown 이벤트가 중복으로 발생하게 되는 것이다.
즉, IME를 통해 한글, 일본어, 중국어 등을 변환하는 과정(composition)에서 keydown 이벤트는 OS 뿐만 아니라 브라우저에서도 처리되기 때문에 중복 발생된다.
정리하자면 웹소켓 통신 문제가 아니라, input에서 입력값 문자를 처리하는 방법에 의해 발생한 문제였다.
해결 방법
Web API 스펙의 event target을 보면 KeyboardEvent.isComposing 이라는 프로퍼티를 제공한다. 자세한 설명을 보면, composition Session 중에 event가 발생하는지 여부를 불리언 값으로 반환한다고 명시되어 있다. (The KeyboardEvent.isComposing read-only property returns a boolean value indicating if the event is fired within a composition session)
즉, 한글 등 비영어권 언어를 표현하는 과정에서 이 값을 참조하면 true값을 반환한다.
비영어권 언어의 변환이 완전히 끝나면 isComposiong이 false가 되므로,
event.isComposing === true일 때는 return;해서 sendMessage 함수를 작동시키지 않고,
false가 되었을 때만 전송하도록 바꾸면 된다.
const sendMessage = () => {
socket.emit("chat message", input);
setInput("");
};
const activeEnter = (e) => {
if (e.isComposing) return; // 비영어권 언어 중복 입력 방지
if (e.key === "Enter") {
sendMessage();
}
};
참고 자료
React, 한글 입력시 keydown 이벤트 중복 발생 현상
React 에서 한글 입력 시 keydown 이벤트가 중복으로 발생하는 문제를 해결하는 방법을 소개한다
velog.io
'JS' 카테고리의 다른 글
| 이중 부정(!!) (0) | 2025.03.01 |
|---|---|
| Three.js + Webpack 프로젝트를 github pages로 배포 후, 이미지 경로 못 찾는 문제 (0) | 2025.02.22 |
| debounce & throttle (0) | 2025.01.05 |
| 나의 첫 'REST API' 사용 (0) | 2024.09.16 |
| 리턴값으로 프로미스를 반환하는 함수 사용법 (0) | 2024.09.10 |
