내가 보려고 만든 개발 공부 일지

keydown 이벤트 한글 중복 입력 현상 본문

다양한 삽질들

keydown 이벤트 한글 중복 입력 현상

kwangsunny 2021. 12. 23. 01:07

React로 카카오톡과 같은 채팅 컴포넌트를 만들던 중 발견한 버그와

해결한 방법을 기록해봅니다.

 

Chatting.tsx

위 이미지는 내가 만들고있던 Chatting.tsx 컴포넌트다.

기록된 메시지들이 보이는 부분이 ChattingList.tsx 이고,

메시지를 입력하는 아랫부분이 ChattingInput.tsx 이다.

 

ChattingInput 에 텍스트를 입력하고 Enter를 누르거나 전송을 클릭하면 입력된 텍스트가

ChattingList에 추가되는 기능을 구현했다.

그런데, 영문을 입력하면 정상적으로 ChattingList에 잘 추가가 되었지만 이상하게 한글만 입력하면

입력된 텍스트와 그 텍스트의 마지막 부분이 잘려서 두번 이벤트가 발생하는 것이었다...

 

좌 : 영문입력    /    우 : 한글입력

위 이미지와 같은 현상이 발생했다.

그래서 개발자도구에서 breakpoint를 찍고 디버깅을 해보니 이때는 한글 입력도 정상 입력이 되었다..

breakpoint 를 찍고 멈췄다가 다시 실행시키면 정상동작 하는것을 보면서 아무래도 내가 사용한 이벤트 함수가 동작하는 메커니즘에 의한 현상일 것이라는 생각이 들었다.

 

아래는 ChattingInput의 일부 코드이다.

// ChattingInput.tsx
const onKeyDown = (e: React.KeyboardEvent<HTMLTextAreaElement>)=>{
    if(e.code === 'Enter'){
        e.preventDefault();
        handleSendMessage();
    }
}

...

return (
    <div css={style}>
        <textarea value={msg} onKeyDown={onKeyDown} onChange={onChange}/>
        <button className='send-btn' disabled={disabled} onClick={handleSendMessage}>전송</button>
    </div>
);

 

위와 같이 keydown 이벤트로 Enter입력을 구분해주었는데, 나는 keydown 이벤트가 '단순히 키가 눌렸을때 발생하는 이벤트' 정도로만 알고있지 내부 동작은 자세히 모른다는 생각이 들었다.

그래서 구글링을 해보던중 흥미로운 글을 하나 읽게되었다.

 

the keydown event is also fired during IME composition, to improve cross-browser compatibility for Chinese, Japanese and Korean users.
We can ignore the keydown event during IME composition, we can check the isComposing property of the event object that’s provided by the keydown event handler 
.....
Whenever, we type in Chinese, Japanese or Korean, the isComposing property will have the value true and the keyCode property will have the value 229.

 

출처 : https://levelup.gitconnected.com/javascript-events-handlers-keyboard-and-load-events-1b3e46a6b0c3

 

JavaScript Events Handlers — Keyboard and Load Events

In JavaScript, events are actions that happen in an app. They’re triggered by various things like inputs being entered, forms being…

levelup.gitconnected.com

 

위 내용을 대충 해석하면, 한글이나 중국어같이 영어가 아닌 글자들은 한 글자가 영어보다 많은 정보를 담고있기 때문에

키입력 순간부터 입력완료 까지 시간이 걸리고, 이는 keydown 이벤트가 이미 발생되고 난 후에도 진행중일 수 있다는 것을 의미하고 그 상태를 isCompsing 이란 event 객체 속성값으로 확인 할 수 있다는 것이다. 

 

그러니까 ChattingInput 에서 'test' 가 아닌 '테스트' 를 입력했을때 keydown 이벤트 함수는 호출된 상태지만 실제로 

'테스트' 라는 글자는 아직 isComposing == true 상태인 것이고(= 글자가 구성되고있는 중) 

이 때문에 글자가 중복되서 화면에 찍히는 현상이 나타났던 것이다.

 

 

 

 

그래서 찾은 대안으로 keydown 대신 keypress를 사용했더니 위와같은 문제는 발생하지 않았다.

이게 올바른 대처법인지는 확실치 않지만 일단은 이게 최선의 해결책인것 같아 이렇게 처리해 주었다. 

 

 

 

 

'다양한 삽질들' 카테고리의 다른 글

React hooks 에서 useState setter 함수 작동 순서  (0) 2021.07.04
ExpressJS의 use 함수  (0) 2021.07.02
Comments