onKeyPress Enter를 누르고 있을때 중복입력 막기

JohnKim·2022년 3월 28일
0

javascript

목록 보기
26/26

🤬 todolist에서 input에 엔터를 누르고 있을 때 문제 상황

todolist에서 inputvalue가 없다면 TodoViewModel.addTodo함수에서 alret을 띄운다.
그러나 텍스트 입력후 엔터를 누르고 있었더니 다음과 같이 실행이 되었다.

  1. 기존에 입력한 텍스트는 정상적으로 추가가 됨.
  2. 추가 이후 inputvaluenull으로 바뀜
  3. 엔터는 누르고 있는상황을 inputElement는 계속 입력이 된다고 onkeypress 이벤트를 실행함.

🧐 내가 원하는것은 엔터를 누르고 있어도 한번만 실행되기를 바라는건데... 왜 계속 실행이 되는거지??

자바스크립트의 키보드 이벤트는 3가지가 존재한다.

onKeyUp : key 누름이 해제될때

onKeyDown: key를 눌렀을때

onKeyPress: key가 눌린 상태일때, 현재는 사용되는것을 추천하지 않는다고 합니다.

     <input
          type="text"
          value={TodoViewModel.createInputValue}
          onChange={(e) => TodoViewModel.handleCreateInput(e.target.value)}
          onKeyDown={(e) => e.key === 'Enter' && TodoViewModel.addTodo()}
          autoFocus
        />

우선 현재는 사용되는것을 권장하지 않으니 keyDown이벤트로 변경해주었다.

하지만 여전히 문제는 해결되지 않았다....

그래서 처음에는 상태값을 생성하여 boolean 값으로 submit 유무를 판단하여 이벤트 재실행을 막으려고 하였다.

그러나 MVVM 패턴을 적용하며 만들고 있던 todolsit였기 때문에 view에서 변수를 생성하여 로직을 처하거나 viewModel에서 이거 중복입력막으려고 로직을 또 추가하는게 비효율적이라고 생각이 들었다.

해결방법

blur 이벤트로 한번 todo가 submit 되고 나서 input 포커싱을 바깥으로 빼버리는 것으로 해결을 하였다.

.blur()는 모든 요소가 아닌 HTMLElements에만 존재하도록 보장되기 때문에 as HTMLInputElement라고 target이 HTML Element임을 지정할 필요가 있다.

  <input
          type="text"
          value={TodoViewModel.createInputValue}
          onChange={(e) => TodoViewModel.handleCreateInput(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === 'Enter') {
              (e.target as HTMLInputElement).blur();
              TodoViewModel.addTodo();
            }
          }}
          autoFocus
        />

0개의 댓글