평소처럼 애용하는 react-hook-form
을 사용해서 자동완성을 구현하려하는데, 생각해보니 그냥 onChange
를 활용하면 너무 통신이 잦아질 것 같다는 생각이 들었다. 그래서 어떻게 방법이 없나 찾아보았는데.
stack-overflow에서 onChange안에 다가 handleSubmit을 넣으면 onChange마다 제출이 가능하다는 글을 보게 되었다.
onChange={(e) => {
setValue("firstName", e.target.value);
handleSubmit((data) => console.log("data", data))();
}}
여기서 setValue, handleSubmit
은 useForm에서 가져온다.
그래서! 저 함수를 lodash
의 debounce
로 감싸주기로 했다.
<Controller
control={control}
name="searchWord"
render={({ field: { name, onChange } }) => {
return (
<TextField
name={name}
onChange={_.debounce(e => {
setValue('searchWord', e.target.value);
handleSubmit(onSearchWordSubmit)();
}, 300)}
/>
);
}}
></Controller>
그 결과
이렇게 통신의 양이 줄어들었다!
onChange안에서 작성과 제출을 동시에 한다는 아이디어가 너무 좋았던 것 같다.
// 임시로 debouncing 함수
// timer, setTimer = useState(0)
// fn : async () => await {} 함수
// delay : delay 시간
// 컴포넌트
const [timer, setTimer] = useState(0);
const submitFn = (data) => {
debounceCallback({
timer,
setTimer,
fn : async ()=> {
await ~~
},
delay : 1500,
})
}
<Compoenent onSubmit={handleSubmit(submitFn)}>
// debounceCallback
export default function debounceCallback({ timer, setTimer, fn, delay }) {
if (timer) {
console.log('clear timer');
clearTimeout(timer);
}
const newTimer = setTimeout(fn, delay);
setTimer(newTimer);
}
ajax 요청에 대한 debouncing을 적용해야 되서 찾아 찾아 이렇게 구현했다. 코드가 너무 더러워서 어떻게든 수정을 해보긴 해야겠다...