🤔 input창을 사용할 때 onchange 이벤트나 scroll 이벤트등 한꺼번에 많이 일어나는 이벤트들을 처리하는 경우 최적화해줄 필요가 있다.
🧚 라이브러리를 사용할 수도 있지만 간단하니 디바운싱을 직접 구현해보자
연이어 호출되는 함수들 중 마지막 함수(또는 제일 처음)만 호출하도록 하는 것
let timer;
document.querySelector('#input').addEventListener('input', () =>
if (timer) { // 이전 요청의 timer가 남아있다면 지우기
clearTimeout(timer);
}
timer = setTimeout(() => { // 초기설정 혹은 덮어쓰기
//API 요청
}, 400);
);
마지막 함수가 호출된 후 일정 시간이 지나기 전에 다시 호출되지 않도록 하는 것
몇 밀리초에 한 번씩만 실행되게 제한을 두는 것
let timer;
document.querySelector('#input').addEventListener('input', () =>
if (!timer) { // timer 없으면 실행
timer = setTimeout(() => {
timer = null; // 시간 지난 후 timer 해제
// timer 해제 후 API 요청
}, 400);
});
📃 Parent.js
import { useState } from 'react';
// API
import { updateMemberById } from '../../lib/api/memberApi';
function parent() {
// 데이터 관리
const [memberState, setMemberState] = useState({
member: null,
});
const [timer, setTimer] = useState(0); // 디바운싱 타이머
const onChangeInputs = async evt => {
...
setMemberState({ // client data는 바로 변경
member: memberData,
});
...
// 디바운싱 - 마지막 호출만 적용 (put api)
if (timer) {
console.log('clear timer');
clearTimeout(timer);
}
const newTimer = setTimeout(async () => {
try {
await updateMemberById(match.params.id, memberData);
} catch (e) {
console.error('error', e);
}
}, 800);
setTimer(newTimer);
};
...
return (
<Child
onChangeInputs={onChangeInputs}
memberState={memberState}
/>
);
}
📃 Child.js
function child({ onChangeInputs, memberState }) {
return (
<Input
name="introduction"
value={memberState.member.introduction}
onChange={onChangeInputs}
/>
)
}
이렇게 적어주면 0.8초 안에 연속으로 들어온 이전 요청들은 clear되고 마지막 요청만 실행된다.
감사합니다!