Input 태그 한글 입력 시 중복으로 입력되는 문제

coggiee
5 min readJul 1, 2024

--

데브코스의 결실을 맺는 최종 프로젝트 진행 중에 해당 문제가 발생했다.
현재 모각Go라는 타이틀로 모각코 매칭 서비스를 주제로 한 프로젝트를 진행 중이다.
프로젝트 카드(=매칭 글)를 생성할 때 모각코의 분위기 태그를 입력받는 Input이 존재하는데, 한글을 입력할 시 중복 이벤트가 발생했고 이를 수정해야했다.

문제 상황

보다시피, 한글을 입력하면 마지막 음절에 밑줄이 발생한다.
그리고 Enter를 입력 시, 사진에서 볼 수 있듯이 마지막 음절이 추가로 입력되는 현상이 발생한다.

문제 발생 원인

IME의 글자 합성 때문에 발생하는 문제이다.
IME는 자음과 모음을 합성하여 하나의 글자를 만들어주도록 도와주는 역할을 한다.

예를 들어, '한국'이라는 단어는...

  • IME가 없다면: ㅎㅏㄴㄱㅜㄱ으로 표현된다.
  • IME가 있다면: 한국으로 표현된다.

(한글에서만 발생하는게 아니라 조합을 통해 글자가 만들어지는 중국어, 일본어에서도 발생한다고 한다.)

정확히 왜 발생 하는가를 찾아보니,
keydown 이벤트가 발생하면 OS와 브라우저에서 해당 이벤트를 모두 처리하기 때문에 keydown 이벤트가 중복으로 발생하게 되는 것이라고 한다.(참고)

해결 방법

글자 합성에서 발생하는 문제라면, 합성 중과 합성 완료 시점을 파악하여 태그의 추가 여부를 지정하면 된다.

찾아본 해결 방법은 2가지이다.

  1. CompositionEventCompositionStart, CompositionEnd 활용
  2. navtiveEventisComposing 속성 활용

CompositionEvent 활용

글자의 조합이 끝났을 경우에, 태그를 추가하도록 하면 된다.

const [isComposing, setIsComposing] = useState<boolean>(false); // 글자가 조합 중인지 판별하는 boolean 값
const handleCompositionEvent = () => {
setIsComposing(prev => !prev);
}
const handleAddTag = (e: KeyBoardEvent<HTMLInputElement>) => {
if (isComposing) return;
... // 태그 추가하는 로직 작성
}
return (
<input
onCompositionStart={handleCompositionEvent}
onCompositionEnd={handleCompositionEvent}
onKeyDown={handleAddTag}
/>
);

nativeEvent 활용

nativeEventisComposing 옵션을 제공한다. (위에서 직접 작성한 CompositionEvent를 핸들링하는 코드라고 봐도 될 것 같다.)

const handleAddTag = (e: KeyBoardEvent<HTMLInputElement>) => {
if (e.nativeEvent.isComposing) return;
... // 태그 추가하는 로직 작성
}
return (
<input
onKeyDown={handleAddTag}
/>
);

+) 텍스트 입력과 관련된 이벤트의 계층 구조 ?

CompositionEvent에 대해서 살펴보다가 텍스트 입력 이벤트의 계층 구조가 존재한다는 것을 알게됐다.
CompositionEvent, UIEvent, Event가 속해있다.

이벤트의 발생 순서는 아래와 같고, 한글을 타겟으로 가정했다.

  1. CompositionEvent: 한글 입력과 관련된 이벤트. compositionstart, compositionupdate, compositionend가 순서대로 발생한다.
  2. compositionstart: 한글 입력이 시작될 때 발생하는 이벤트로, 한 번만 발생하며, 한글 입력 모드 진입 시 초기화 작업을 수행하는데 사용된다.
  3. compositionupdate: 한글 입력 중에 발생하는 이벤트로, 입력된 텍스트의 변경사항을 나타낸다. 사용자가 텍스트를 입력하거나 수정할 때 발생한다.
  4. compositionend: 한글 입력이 종료될 때 발생하는 이벤트로, 한 번만 발생하며 한글 입력이 완료되고 입력 모드가 종료될 때 사용된다.
  5. UIEvent: 사용자 인터페이스와 관련된 이벤트. 일반적으로 마우스나 터치 등의 사용자 입력에 의해 발생한다. CompositionEvent 이벤트가 완료된 후에 발생할 수 있다.
  6. Event: 일반적인 이벤트. CompositionEventUIEvent 가 완료된 후에 발생할 수 있으며, 다양한 이벤트 유형을 다룬다. (e.g. KeyboardEvent, MouseEvent, FormEvent)

즉, 텍스트 입력과 관련된 CompositionEvent가 가장 먼저 발생하고, 그 후에 UIEvent와 Event가 발생한다. 발생 순서는 이벤트의 종류와 사용자 동작에 따라 달라질 수 있다.

정확한 정보인지는 더 찾아봐야겠지만, 위와 같은 계층 구조로 인해 OS와 브라우저에서 해당 이벤트를 모두 처리하여 keydown 이벤트가 중복으로 발생하게 되는 것이 아닐까라고 추측 정도만 하고 있다.

추가적으로, contenteditable속성을 사용해서 간단한 에디터를 만들었을 때 한글의 자소 분리 현상이 있었는데 이도 IME의 문제 때문이지 않을까 생각한다.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

coggiee
coggiee

Written by coggiee

0 Followers

Just doing

No responses yet

Write a response