본문 바로가기
Language/JavaScript

한글 입력 시 Enter 이벤트 중복 호출 문제 해결

by 그랴 2024. 4. 21.

문제 상황

태그를 입력하는 Input 컴포넌트를 만들던 중, 영어를 입력할 때는 정상적으로 작동하지만

한글을 입력하면 태그가 2개로 나뉘어 생성되는 문제가 발생했다.

 

태그를 생성하는 방식은 아래처럼 구현했다.

  1. 사용자가 태그 이름을 입력한다.
  2. 사용자가 태그 이름 입력을 마치면 엔터 키를 누른다.
  3. 엔터키를 누르는 이벤트가 발생하면, 입력 값을 태그로 생성한다.

 

디버깅

태그를 생성하는 함수 내에서 콘솔을 출력해보니, 한글의 경우에는 한 번만 엔터 키를 클릭해도 이벤트가 중복 호출되었다.

 

 

문제 원인

한글은 자음과 모음이 합쳐져 만들어지는 조합 문자이기 때문에, 글자가 조합 중인지 조합이 완료된 상태인지 파악하기 어려워 이벤트가 중복 호출된다.

 

현재 코드에서 사용중인 onKeyDown 메서드의 경우, 문자의 입력이 아닌 단순 엔터 키 클릭에 대해 반응하는 메서드이기 때문에 이러한 문제가 발생하는 것으로 생각된다.

 

해결 방법

이를 해결하는 방법으로는 2가지가 있다.

 

1. onKeyPress 메서드 사용하기

onKeyDown 메서드와는 달리, 현재 눌린 문자에 대해 반응하기 때문에 가장 간단하게 이 문제를 해결할 수 있다.

하지만, onKeyPress 메서드는 deprecated 되었기 때문에 이 방법은 좋지 않은 듯하다.

 

2. isComposing 사용하기

KeyboardEvent에는 isComposing이라는 값이 존재하는데, 문자가 조합 중인지를 boolean 값으로 알려준다.

 

KeyboardEvent: isComposing property - Web APIs | MDN

The KeyboardEvent.isComposing read-only property returns a boolean value indicating if the event is fired within a composition session, i.e. after compositionstart and before compositionend.

developer.mozilla.org

현재 해결하고자 하는 문제가 한글이 조합 중인지를 판단하지 못해 발생한 문제이기 때문에 이를 사용하면 될 듯하다. 

따라서, 아직 글자가 조합 중인 경우에는 ealry return 시켜주고, 조합이 완료된 경우에만 태그 생성 로직을 실행시켰다.

  const makeTag = (e: React.KeyboardEvent<HTMLInputElement>) => {
    if (e.key === 'Enter') {
      e.preventDefault()
      if (e.nativeEvent.isComposing) {
        return
      }
      const inputElement = e.target as HTMLInputElement
      setTags([...tags, inputElement.value.trim()])
      inputElement.value = ''
    } else if (e.key === 'Backspace' && e.currentTarget.value === '') {
      setTags(tags.slice(0, -1))
    }
  }

 

 


참고 자료

 

[JavaScript] 한글 키보드 입력 시 이벤트가 두 번 호출되는 경우

문제상황 Ant Design의 Input에 onPressEnter를 사용하는 중 위와 같은 문제가 발생했다. 텍스트를 입력하고 엔터를 누르면 Select의 옵션 값으로 추가가 되도록 구현했는데, 함수가 두 번씩 호출되어 텍

doqtqu.tistory.com

 

한글 입력 시 중복 이벤트 발생

contentEditable은 어떤 HTML 요소든 input이나 textarea처럼 텍스트를 작성하고 수정할 수 있는 상태로 만들어주는 속성이다.

medium.com