debounce는 dom 스크롤이나 숫자 입력에 따른 API 호출 같은 이벤트가 과도하게 호출하는 경우 지정한 시간 동안 호출에 제약을 걸어 API 과호출을 방지하는 기술이다.
한마디로 호출 시 지정된 시간 이후 호출된 가장 마지막 이벤트만 실행되는 기술을 말한다.
lodash라는 서드 파티 라이브러리에서 debounce를 지원한다.
리액트에서 lodash를 사용할 때 유의할 점이 있는데, 리렌더링 되는 컴포넌트내에 debounce를 정의한 함수가 있고, 해당 컴포넌트가 state에 따라 리렌더링 된다면 debounce 함수도 재생성되면서 debounce가 초기화 된다는 점이다.
이를 방지하기 위해서는 useCallback을 사용해 state가 바뀌어도 debounce 함수가 재생성되지 않도록 하면 초기화를 방지할 수 있다.
실제로 회원가입에 아이디 중복 체크를 위해 사용하는 코드 일부다.
const SignUp = ({changeAuthMode, setIsRegistered}) => {
const [isCheckId, setIsCheckId] = useState(false);
const **debounceCheckId** = useCallback(
debounce((userId) => {
axios.get(`${process.env.REACT_APP_API_MYSHOP}/customer/exists/id/${userId}`)
.then((response) => {
setIsCheckId(true);
})
.catch((err) => {
setIsCheckId(false);
});
}, 300),
[]
);
// onChange={inputHandler}
const inputHandler = useCallback((e) => {
const {name, value} = e.target;
setFormData({
...formData,
[name]: value
});
switch (name) {
case "userId":
**debounceCheckId**(value);
break;
default:
}
}, [formData]);
...
}
input 값의 변경을 감지하기 위해 input 태그의 onChange 속성으로 inputHandler 함수를 넣어 state를 관리하는데, 그 중 name 속성의 값이 “userId”라면 debounceCheckId를 호출하게 되고 이 함수 내부에서 input 값에 해당하는 값의 중복 체크 api를 호출하게 된다. 여기서 2번째 파라미터로 사용된 300의 값은 0.3초내에 들어오는 마지막 호출만 함수의 내용을 실행한다는 뜻이다.