2 분 소요

TIL

TIL 및 구현 사항

Number Type Input

Number Type input에서 ‘-‘를 포함하여 모든 문자/특수문자가 입력되지 않도록 하려고 했다.

처음 접근법

keydown으로 문자 입력을 막자

  1. chrome에서는 input에 number type을 주면 숫자를 제외한 나머지는 JS 처리 없이 입력되지 않는다.
    그러나 이마저도 -, +, e, E는 숫자로 간주되어 입력이 된다.

    이를 없애려

    <input onKeyDown={ (e) => ['e', 'E', '-', '+'].includes(e.key) &&
    e.preventDefault() } />
    

    이렇게 했으나

    chrome에서만 다음과 같이 적용되고 나머지 브라우저에서는 숫자가 아닌 입력(non-numeric input) 또한 입력이 되도록 설정되어 있기 때문에 이는 좋은 해결방법이 아니다.

  2. 따라서 애초에 onKeyDown 때 숫자만 입력되도록 하려고 했다.

    처음에 다음과 같이 정규식으로 구현했다.

    <input onKeyDown={ (e) => { if(!/^[0-9]+$/.test(e.key)) { // isNumber는
    lodash에서 사용 e.preventDefault() } } } />
    

    그러나 이렇게 되면 숫자가 아닌 입력에서는 아예 동작이 불가능하다.
    Backspace나 enter, tab, 방향키는 무조건 동작해야한다.

    따라서 다음과 같이 조건을 추가하였다. (special keys / function keys 를 구별)

    <input onKeyDown={ (e) => { if (!/^[0-9]+$/.test(e.key) && e.key.length ===
    1) { e.preventDefault() } } } />
    

    이렇게 enter, backspace 등과 같은 key들을 구별하는 함수가 lodash에도 없고,
    정규식으로도 할 수 없는 부분이기 때문에
    length가 2자 이상인 것은 캐릭터가 아닌 펑션 키들을 나타내는 것이므로 다음과 같이 조건을 추가했다.

    이렇게 하면 보통의 경우에 동작하기는 한다.

    그러나 e.key.length === 1 매우 마음에 들지 않는 조건이다.

  3. 문자/특수문자가 포함된 string을 복/붙했을 때 처리
    생각해보니 문자/특수문자가 포함되어있는 문자열을 복사해서 input에 붙여넣었을 때 동작을 생각해보아야 한다.

    키보드로 입력 시 복사 붙여넣기가 아예 되지 않았다. (ctrl 에서 v를 눌러야하지만 v가 눌리지 않기 때문에)

    그러나! 마우스로 붙여넣을 때는 보기좋게 붙여넣어졌다ㅎㅎ

    그래서 input 컴포넌트에 onPaste 이벤트 핸들러를 추가하여 기본동작을 막았다.

    onPaste={e => e.preventDefault()}
    

    심히 마음에 들지 않았다. 무언가 잘못하고 있다는 느낌을 지울 수 없었다.

    첫번째로 예외 처리를 하는 데에 코드가 장황해졌다.
    두번째로 이렇게 되면 다른 예외 상황에 대해서 커버되지 않는다는 것을 뜻한다.

    그래서 키가 눌렸을 때가 아닌 input 값에 변화가 있을 때를 핸들링하여 필터링을 해야한다고 생각했다.

  • 삽질하다 발견한 점

    e.which, e.keyCode, e.CharCode는 곧 종료될 예정.
    onkeypress는 deprecated로 사용을 권장하지 않음.
    input type number 일 때 chrome에서만 non-numeric이 입력 불가.
    input type number일 때 (e, E, -, +) 입력 시 input이 초기화된다.

두번째 접근법

onChange 핸들러에서 input 값을 숫자만 필터링

<input onChange={handleExtractNumberFromValue} />

onChange로 키가 눌렸을 때는 물론, 어떠한 방법으로든 input 값에 변화가 일어나면
변화된 값을 정규표현식으로 숫자만 필터링하여 input value를 다시 set 해주었다.

const handleExtractNumberFromValue = (e: React.ChangeEvent<HTMLInputElement>) =>
  setValue("phoneNumber", e.target.value.replace(/[^0-9]/g, ""));

결과는 성공적이었다!!

//////////////// 코드 및 이미지 추가 필요 (주말에)

회고 (TIL)

2022.04.19 Daily 회고

✏오늘 한 일

  • 마이너 업무
    • 이미지 비율 문제 개선
    • 숫자 입력 ‘-‘ 입력 방지 (feat. react-hook-form)
  • 디자인 시스템 공부
    • storybook 써보기

⁉느낀 점

어떻게 프로젝트가 돌아가고 있는지는 대충 따라가고 있다고 생각한다.

그러나 지라에 올라온 현재 업무들을 할 수 있을까가 걱정된다.

UI 관련 작업은 그냥 시간을 투자하고 질문해가면서 할 수 있을 것이라고 생각이 드나
백엔드와 협업하여 데이터를 요청하는 등의 작업은 어떻게 하게 될 지 궁금하기도 하고 걱정도 된다.

일단 라이브러리 공부하고, 업무들 연습하면서 꾸준히 코드 분석하고, 코드 이해도를 높이는 것이 먼저일 것 같다.

rollup과 storybook, yarn berry, 디자인 시스템에 관해 계속 공부해야한다. (처음부터 맡게 될 업무이다보니 미리 공부하는 게 좋을 것 같다.)

🎃현재 나의 상태

허리 아프다. 왜 아무도 스탠드 책상을 안쓰는거야!!


태그: ,

카테고리:

업데이트:

댓글남기기