키업 이벤트를 기반으로 한 유효성 로직의 단점 가운데 가장 컸던 것이, 모든 입력마다 유효성 이벤트가 실행된다는 것이었다. 입력마다 즉각적으로 반응해주는 것은 유저에게는 장점으로 다가올지 몰라도, 개발자에게는 그리 좋은 흐름은 아니다. 한 유저당 20자의 이메일 정도를 생각하고, 100명을 계산하면 이메일 검사만 하는데, 2000번의 이벤트가 실행되어야 한다. 디바운싱을 통해 해당 단점을 개선해보자. setTimeout
과 clearTimeout
을 이용한 디바운싱이다.
사실 setTimeout으로 밖에 할 줄 모른다.
let checkValid
function inputValidHandler() {
clearTimeout(checkValid)
checkValid = setTimeout(() => {
let errorComponent = ''
for (let func in onValid) {
if (!onValid[func].func(inputRef.current.value)) {
errorComponent = <ErrorComponent text={onValid[func].message} />
break
}
}
console.log('유효성 체크')
setErrorComponent(errorComponent)
onData({
value: inputRef.current.value,
valid: errorComponent === '' ? true : false,
})
}, 500)
}
동작 원리는 이렇다. setTimeout
의 콜백함수가 콜백 큐에 들어가기 전, 컴포넌트 재평가를 통해, clearTimeout
을 다시 만나게 되고, 사라지게 된다. 그러고 다시 또다른 setTimeout
함수가 생성되게 된다. 이러한 과정이 유저가 키업 이벤트를 할 때 계속되다. 유저가 마지막 키업 이벤트를 한지 500ms가 지나면, 더이상 컴포넌트 재평가가 이루어지지 않은 체, clearTimeout
을 만나지 않게 되고, 현재 가지고 있는 inputRef
의 값으로 유효성 로직을 실행하게 할 수 있다.
유효성 검사 로직을 조금 더 확장하였다. 각 사용하는 input
컴포넌트의 상태를 저장하는 useState()
함수를 생성하고, 현재의 input
값과, 유효성 상태를 저장하도록 했다. 현재 가지고 있는 모든 state
객체의 유효성 값이 true
인 경우에만, login
이벤트를 실행하도록 했다. login
이벤트에는 서버를 통해 해당 입력 값이 user
데이터베이스에 존재하는지 확인한 후, 성공이라면 공유 객체 데이터에 해당 값을 저장하고 아닌 경우는 로그인에 실패했다는 에러를 던지면 된다.
드디어 이제는 상태관리 라이브러리가 필요해졌다. 내일은 해당 셋팅을 할 것이다.
발표 준비도 해야하니 빠르게 빠르게 움직이자.