onChange 이벤트는 input에 변화가 감지될 때마다 호출된다. e.target.value
을 console에 찍어보면 자음, 모음까지 나뉘어진 단위로 출력된다.
해리포터를 검색할 때 'ㅎ', '핼', '해ㄹ' 이런 검색어는 필요가 없다. 이러한 쿼리를 모두 API에 담아서 보낸다면 불필요한 API 요청이 발생할 것이다.
이 문제는 lodash 라이브러리의 debounce 메서드를 사용하면 해결할 수 있다.
lodash는 자바스크립트의 인기 라이브러리다. debounce나 throttle처럼 구현하기 번거로운 함수들을 제공한다.
- throttle: 지정된 시간 동안 함수가 최대 한 번만 호출되도록 함수 호출 최대 횟수를 조절하는 방법이다.
- debounce: 함수가 호출되는 속도를 제한하여 불필요하게 호출이 자주 일어나지 않도록 하는 방법이다.
npm install lodash
타입스크립트
npm install --save @types/lodash
_.debounce( func, wait, options )
const [query, setQuery] = useState("");
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setQuery(e.target.value);
fetch(`https://api.themoviedb.org/3/search/movie?api_key=${process.env.REACT_APP_KEY}&query=${e.target.value}`)
.then(res => res.json())
.then(data => {
if(!data.errors) {
setResults(data.results);
} else {
setResults([]);
}
})
}
...
<input
type="text"
placeholder='영화 제목을 입력하세요.'
onChange={ onChange }
/>
const [query, setQuery] = useState("");
const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
// debounce로 값 넘기기
debouncedSearch(e.target.value);
}
// debounce 최적화
const debouncedSearch = useMemo(() => debounce((query) => {
// 모든 호출이 아닌
// 지정 간격 마다 리턴 값 받아서 state에 담고
setQuery(query);
// 그 값으로 API 데이터 가져오기
fetch(`https://api.themoviedb.org/3/search/movie?api_key=${process.env.REACT_APP_KEY}&query=${query}`)
.then(res => res.json())
.then(data => {
if(!data.errors) {
setResults(data.results);
} else {
setResults([]);
}
})
}, 200), [ query ]);
...
<input
type="text"
placeholder='영화 제목을 입력하세요.'
onChange={ onChange }
/>