input에 숫자만 입력되게 하고싶을 경우 사용가능한 방법 Show
업무를 하면서 카드결제시 카드번호 작성 인풋이나 더 좋은 방법이나 위 방법이 잘못된점이 있다면 지적해주세요! Photo by Alexandre Debiève on Unsplash form을 만들다보면 여러가지 input을 쓰게된다. 그 중에서 number input은 많은 곳에 사용되지만 불행히도 html5에서 제공되는 type=”number”가 우리의 입맛에 맞는 경우는 잘 없다. 그래서 numberInput을 react로 만들어보기로
했다. 우선 number input하면 필요한 내용을 아래와 같이 정리해 보았다.
위를 props로 정리하면 아래와 같다. interface NumberInputProps {decimal: number; // 소수점 몇자리까지 받을 것인지 필요하다 우리가 render할 DOM은 input밖에 없으므로 render는 간단하게 처리가 된다. 현재 우리가 설계한 내용에서 필요한 이벤트는 focus(selectOnFocus)와 change(value 변경처리), keydown(up, down value) 그리고 마지막으로 input의 값을 이쁘게 변경해줄 blur 이벤트면될것이다. render() { return ( 다음으로 연결할 이벤트를 만든다. onChangereact에서 제공하는 onChange는 실제 dom의 onchange(실제 blur시에만 발생한다)와는 다르다. 이는 사실 물리적인 입력을 인지하는input
event 우선 input의 값 변경 처리에 대한 결정이 필요하다.
react의 경우 모든 dom의 변경은 state를 통해 이루어지는 것이 좋으나 실제 input을 만들어 보면 그것이 좋은 방법인지는 잘 모르겠다. interface State { strValue: string; 다음으로 실제 onChange에서 처리할 로직이다. 잘못 입력된 글자(숫자를 제외한 값)들을 제거한다. 실제 number input의 경우 .(소수점)와 e(5-e7을 같은 지수값을 위해)를 입력가능하지만 일반적인 앱에서 저 값을 입력할 일은 없으니 삭제 범위는 [^\d\-.](숫자와 minus 기호, 소수점을 제외하고 소수점이 따라오지 않는 시작점의 0도 삭제한다)로 정한다. // digit 별로 필요없는 글자를 지운다. input에 입력된 ‘0.00’ 과 ‘0’이 숫자로는 같은 0을 나타내기 때문에 numValue와 strValue 두개를 따로 저장한다. emit되는 값이 글자라면 위처럼 numValue를 굳이 저장할 필요는 없다. onFocusonFocus의 역할은 두 가지이다. onFocus(e: SyntheticEvent<HTMLInputElement>) { onBluronBlur에서는 마지막으로 기존 숫자 기본형 포맷대로 정리를 해주는 역학을 한다. 이전처럼 0을 0.00으로 놔둘시 다른 처리를 할때 귀찮을 수 있으므로 이곳에서 format을 통일시킨다. (아직 options에 대한 정의는 이루어지지 않았다.) onBlur(e: SyntheticEvent<HTMLInputElement>) { const value = e.currentTarget.value; if (["", ".", "-"].indexOf(value) > -1) { onKeyDown마지막으로 onKeyDown이다. onKeyDown 같은 경우 dirty체크를 하기 위해 사용되고 readonly 이거나 disabled 일때 입력을 제어할 수 있어야 한다. onKeyDown(e: KeyboardEvent<HTMLInputElement>) { 이제 추가 기능으로 masking을 넣을 것이다. maskingmasking은 특정 format으로 변경해주는 작업이다. 이를테면 큰 숫자를 입력하는 거래소에서는 자리 수 확인을 위해 ‘,’를 넣는 작업이 필요하다. 이것은 변경이 다 된 strvalue를 setState하기 전에 변경해주면 된다. 또한 외부에서 값을 변경하거나 키보드 업앤다운으로 값이 변경될때 같은 로직을 타야하므로 onChange 내부의 로직을 두개로 분리해서 같이 공유하도록 한다. setValueByRule(value: string) { const sign = value[0] === "-" ? "-" : ""; 이제 우리는 여기 있는 코드를 리팩토링 할것이다. 그를 위해 다음편 에서는 React의 life cycle과 해당 코드의 분리등을 다시 설명하려 한다. 아직 설명되지 않은 callback option 부분이나 safeString의 이유, 그리고 controlled component의 한계는 역시 함께 설명하려 한다. 위의 코드로 처리된 number input의 예제는 아래에서 확인할 수 있다. |