본문 바로가기
React

React(75) shift + enter 줄바꿈 (feat. 두번씩 출력되는 버그처리)

by 새발개발JA 2022. 6. 26.
반응형

 

 

Updated 08/22/22

채팅창에 메시지를 입력할 때, 

엔터키를 치면 전송이 되는 기능과 +  [ shift + 엔터키 ] 로 줄바꿈을 하는 기능

요렇게 두가지를 동시에 구현 중이다.

이 기능들은 키보드 이벤트를 알아야 구현을 할 수 있다. 그럼 이제 구현하러 가보자

 

Hoxy 자바스크립트의 키보드 이벤트에 대해 자세한 개념이 궁금하시다면 ? ( ↓↓↓ 아래포스팅을 확인하세요)

 

JavaScript - KeyDown / KeyPress / KeyUp 이벤트

메시지 입력창에서 엔터키로 메시지 전송을 할 때나 줄바꿈을 할 때 키보드 이벤트를 사용하게 된다. 대표적인 키보드 이벤트인 keyDown / keyPress / KeyUp 에 대해서 정확히 알고싶어서 공부해보았다

devbirdfeet.tistory.com

 

 


 

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 이면 ){
    메시지 보내기() 를 해버린다
  }
}

 

 

 

반응형

댓글