Updated 08/22/22
채팅창에 메시지를 입력할 때,
엔터키를 치면 전송이 되는 기능과 + [ shift + 엔터키 ] 로 줄바꿈을 하는 기능
요렇게 두가지를 동시에 구현 중이다.
이 기능들은 키보드 이벤트를 알아야 구현을 할 수 있다. 그럼 이제 구현하러 가보자
Hoxy 자바스크립트의 키보드 이벤트에 대해 자세한 개념이 궁금하시다면 ? ( ↓↓↓ 아래포스팅을 확인하세요)
React(75) shift + enter 줄바꿈 (feat. 두번씩 출력되는 에러처리)
일단 <input> 태그 안에 onKeyDown 이벤트를 심어주자.
한마디로 keyDown이벤트가 실행되면 onPressEnter 라는 my 함수가 실행된다.
<input onKeyDown={pressEnter} />
그리고 요기는 pressEnter 이다. 여기서 들어가는 내용은 아래와 같다
- isComposing 이라는 속성을 사용한 조합중인 경우의 핸들링
- [ shift + 엔터키 ] 로 줄바꿈하는 기능으로 핸들링
- [ 엔터키 ] 로 메시지 전송 기능 핸들링
const pressEnter = (e: React.KeyboardEvent<HTMLTextAreaElement>) => {
if (e.nativeEvent.isComposing) { // isComposing 이 true 이면
return; // 조합 중이므로 동작을 막는다.
}
if (e.key === 'Enter' && e.shiftKey) { // [shift] + [Enter] 치면 걍 리턴
return;
} else if (e.key === 'Enter') { // [Enter] 치면 메시지 보내기
sendText(e);
}
};
** 왜 keyDown 이벤트를 사용하나요?
맨 처음 나는 keyUp 이벤트를 사용하였다. 그러자 입력한 내용이 두번씩 출력되는 에러가 발생하였다.
도대체 왜 두번씩 찍히는지 감이 안와서 검색도 해보고 사수님께 도움도 요청해봤는데 ... 알고보니...
자세한 뒷 이야기가 궁금하시다면 ? (더보기 클릭)
keyUp과 keyDown의 차이를 잘 알지 못했던 나,
그리고 글자조합에 대한 개념도 잘 알지 못했던 나, (흑흑)
글자조합 & isComposing
일단 글자조합에 대한 개념이 필요하다.
우리는 한글을 쓰는 한국인이다. 한글은 자음과 모음을 조합해야한다.
하지만 알파벳을 쓰는 나라에서 태어난 키보드는 딱히 키보드에 조합을 인식해야 한다는 개념이 없는 것이 함정 🥲
결국 한글을 칠 때 조합이 언제 끝나는지 예측을 못한다는 것이다.
즉, 타이핑을 할때, 하이 → 하잉 처럼 끝을 이 로 끝낼지 잉 으로 조합할지 예측할 수 없다는 것이다.
지금 아무 창이나 띄워놓고 한글을 입력해보시라. 마지막 텍스트에 검정 밑줄 을 발견하게 될 것이다.
검정 밑줄은 아직 조합중이라는 것을 의미한다. 그래서 이에 대응하는 isComposing (조합중) 이라는 속성은 true 가 된다.
두번씩 출력되는 버그
검정 밑줄 이 보일때 Enter 키를 입력하면 이벤트가 2번 발생하는 이슈가 생겼다.
글자가 조합 중인 건지, 조합이 끝난 상태인지 브라우저 입장에서는 예측할 수 없기 때문이다.
그래서 isComposing 으로 조합 중일 경우 이벤트가 동작하지 않도록 만들어 주었지만 여전히 두번씩 출력되었다.
이때 당시 keyUp 이벤트를 사용하고 있었는데, → keyDown 이벤트로 변경하고 모든 문제가 해결되었다.
그이유는 keyboard 이벤트 동작방식을 이해하면 알수 있는 부분이었다.
keyUp / keyDown
내가 사용했던 keyUp 은 키보드를 눌렀다가 뗀 직후, 이벤트가 동작하고, keyDown 은 키를 누를 때 이벤트가 동작한다.
즉, keyUp 이벤트는 키에서 손을 뗀 뒤에 동작하기 때문에 isComposing 에 대한 코드가 동작하지 않게 된 것이다.
(타이핑 후 발생하는 이벤트이기 때문에 어차피 조합은 끝난 후니까 isComposing 은 언제나 false 인 것이다)
** shift + enter 동작원리
키보드 이벤트에서는 사용자가 누르는 키가 무엇인지 감지한다.
즉 어떤 키를 누를 때 특정 동작을 실행하도록 정해줄 수 있고,
특정 동작이 아닌 원래 기능을 사용하도록 무력화 시킬수도 있다.
일단 enter 키는 줄바꿈이 기본기능이다. (CR : Carriage Return / LF : Line Feed)
그럼 enter 를 눌렀을 때 메시지보내기() 기능이 되도록 만들어 주고,
Enter + Shirt 를 동시에 눌렀을 때 메시지 보내기 기능을 막아주면 기본기능동작이 될 것이다 :)
그래서 pressEnter ( 에서 키보드 이벤트를 받아서 ) {
if( e.눌린키 === Enter 랑 e.눌린키 === Shift 이면 ) {
아무 동작 안되게 return 해버린다.
그럼 Enter 키는 원래 줄바꿈 기능이 된다. 얘만 뺀 나머지는 다 전송 된다는 뜻이다.
}
else if( e.눌린 키 === Enter 이면 ){
메시지 보내기() 를 해버린다
}
}
'React' 카테고리의 다른 글
React(77) 스크롤 시, 하위메뉴를 헤더 아래로 고정하기 (0) | 2022.07.12 |
---|---|
React(76) TypeScript - 채팅목록에서 마지막 메시지 보여주기 (1) | 2022.06.27 |
React(74) StoryBook으로 UI 컴포넌트 작업하기 (0) | 2022.06.20 |
React - useState 동작원리 이해하기 (0) | 2022.06.15 |
React- 가상돔(Virtual DOM) 이해하기 (0) | 2022.06.11 |
댓글