useDebounce가 왜 필요한지?
debounce function은 사용자가 미리 결정된 시간 동안 타이핑을 멈출 때까지 keyup 이벤트의 처리를 지연시킨다.
입력된 모든 문자를 처리할 경우 성능이 저하되고 불필요한 로드가 추가될 수 있기에 이를 방지할 수 있다.
useDebounce를 사용하게 된다면 ui 코드가 모든 이벤트를 처리할 필요가 없고 서버로 전송되는 api 호출 수도 크게 줄어들게 된다.
즉, input창에서 검색을 입력할 때 글자 하나하나 마다 이벤트가 처리되는 것을 방지 할 수 있다. 계속 요청이 들어가는 것은 퍼포먼스에 안좋은 영향을 끼치게 된다.
debounce를 이용해서 타이핑시에는 요청이 가지 않도록 하고, 타이핑이 모두 끝났을 때 요청을 하게 한다.
타이핑 시간에 대한 이벤트 동작을 지연을 시킴으로써 성능에 도움을 줄 수 있다.
useDebounce.js
import { useState, useEffect } from 'react'
export const useDebounce = (value, delay) => {
const [debounceValue, setDebounceValue] = useState(value)
useEffect(() => {
const handler = setTimeout(() => {
setDebounceValue(value)
}, delay)
return () => {
clearTimeout(handler)
}
}, [value, delay])
return debounceValue
}
setDebounceValue(value)로 검색어를 치게 되면 delay시간이 지나고 난 후에 debounceValue로 들어가게 된다.
delay시간이 지나가기 전에 타이핑을 더 하게 된다면,
setTimeout이 없어지게 되고 다시 setTimeout이 실행하게 된다.
1을 입력을 했을 때 0.5초가 지나면 setDebounceValue에 들어가지만
0.5초가 되기 전에 2
를 더 타이핑 하면 clearTimeout이 되어서
기존에 1만 입력했던 setTimeout은 사라지게 된다.
즉 1이 .5초가 지나기 전 연달아 2가 입력되면 다시 0.5초가 지나고 나서 setDebounceValue에 들어가진다.
기존에는 1이 입력되면 .5초가 지나고 나서 호출이 바로 되지만
.5초가 지나기 전에 2를 입력하면 delay가 다시 없어지고 2가 넣어진 후 다시 .5초가 호출이 된다.
index.js
const searchTerm = query.get('q')
const debounceSearchTerm = useDebounce(searchTerm, 500)
useEffect(() => {
if (debounceSearchTerm) {
fetchSearchMovie(debounceSearchTerm)
}
}, [debounceSearchTerm]) //처음 렌더링 후 searchTerm이 변경될 때마다 렌더링
const fetchSearchMovie = async (searchTerm) => {
try {
const request = await axios.get(
`/search/multi?include_adult=false&query=${searchTerm}`
)
setSearchResults(request.data.results)
} catch (err) {
console.log('err', err)
}
}
query.get('q')는 검색하고자 하는 value를 넣어준다.
500의 시간이 지나고 나면 호출이 될 수 있게 함.
이제 검색창에 입력을 하게 되면,
해당 검색에 대한 입력이 0.5초가 지나고 나서 통신이 호출되는 것을 확인할 수 있다.