์ค์๊ฐ ๊ฒ์์ด ์๋์์ฑ ์ปดํฌ๋ํธ๋ฅผ ๊ตฌํํ๋๋ฐ, ๊ธฐ์กด์ ์ฝ๋๋ ๊ฒ์์ด input ๊ฐ์ด ๋ฐ๋๋๋ง๋ค ์๋ฒ์ api๋ฅผ ํธ์ถํ๋ค.
์ฑ๋ฅ ๊ฐ์ ์ ์ํด debounce๋ผ๋ ๊ฐ๋ ์ ์ฝ๋์ ์๋ก ์ ์ฉํด๋ณด์๋ค. debounce๊ฐ ์ด๋ค ๊ฐ๋ ์ด๋ฉฐ ์ด๊ฑธ react ์ฝ๋๋ก ์ด๋ป๊ฒ ์ ์ฉํ ์ ์๋์ง ์์๋ณธ๋ค.
๊ธฐ์กด ๊ฒ์ ์ปดํฌ๋ํธ
useEffect(() => {
getLazySearchList(); //api ํธ์ถ
}, [searchInputValue]);
<TextField
placeholder='๊ทธ๋ฃน๋ช
์ ๊ฒ์ํ์ธ์'
value={searchInputValue}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
setSearchInputValue(e.target.value)
}
/>
์ ์ฝ๋์์๋ useState hook์ผ๋ก ๊ด๋ฆฌํ๊ณ ์๋ searchInputValue๊ฐ ๋ฐ๋๋๋ง๋ค ์๋ฒ์ ์์ฒญ์ ๋ณด๋ธ๋ค.
์ง๊ธ ์์ ์ฌ์ง์์ ๋ณด๋ฏ์ด ๊ฒ์์ฐฝ์ ์ ์ ๊ฐ ์๋ ์ฒ๋ผ ์ ๋ ฅํ๋ฉด
ใฑ > ๊ทธ > ๊ธ > ๊ทธ๋ฃจ > ๊ทธ๋ฃน
์ ์ ์ onChange์ด๋ฒคํธ๊ฐ ๋ฐ์ํ ๋๋ง๋ค api๊ฐ ํธ์ถ๋๋ ๊ฒ์ด๋ฏ๋ก ์ฌ๊ธฐ์ ์๋ฒ์ ํธ์ถ์ 5๋ฒ์ด๋ ํ๊ฒ ๋๋ค.
์ฌ์ฉ์ ๊ฒฝํ์ธก๋ฉด์์๋ ์ ์ ๊ฐ ์ ๋ ฅํ๋๋ก ๋ฐ๋ก๋ฐ๋ก ๊ฒ์์ด์ ํด๋นํ๋ ์๋์์ฑ ๋ชฉ๋ก ๊ฒฐ๊ณผ๊ฐ ํ๋จ์ ๋ ธ์ถ๋๋ ์ข๋ค๊ณ ํ ์ ์๋ค. ํ์ง๋ง, ๋ง์ฝ ์ ์ ๊ฐ 100๋ง๋ช ์ด๋ผ๋ฉด??? ์ค์๊ฐ ๊ฒ์๋ง ํ๋๋ฐ `๊ณผ๋ํ API ํธ์ถ`๋ก ์ธํด ์ฑ๋ฅ์ ์ด์์ด ์๊ธธ ์ ๋ ์์ ๋ฟ๋๋ฌ ์๋ฒ์ ๊ณผ๋ถํ๊ฐ ๊ฐ ํ๋ฅ ์ด ์์ฃผ ๋๋ค.
์ด๋ ํ๋ฐํธ๋จ์์ ์ด๋ฐ ๋ฌธ์ ๋ฅผ ์ฒ๋ฆฌํ ์ ์๋ ๋ฐฉ๋ฒ ์ค ํ ๊ฐ์ง๊ฐ ๋๋ฐ์ด์ค์ด๋ค.
Debounce๋?
์ฒ์์ debounce ๋ผ๋ ๋ง์ด ์๋ฟ์ง ์์๋๋ฐ
์์ด์์ de๋ ์ ๊ฑฐ, ๊ฐ์์ ์๋ฏธ๋ฅผ ๊ฐ์ง๊ณ ์๋ prefix ์ด๋ค.
decaffeine ๋์นดํ์ธํ๋ฉด ์นดํ์ธ์ ์ ๊ฑฐํ ๊ฒ์ด๊ณ , defrost๋ frost (์๋ฆฌ)๋ฅผ ์์ ๋ค, ์ผ๋ฆฐ๊ฑธ ๋ น์ด๋ค, ํด๋ํ๋ค๋ผ๋ ๋ป์ ๊ฐ์ง๊ณ ์๋ค.
๊ทธ๋์ debounceํ๋ฉด bounce ์ ํธ๋ฅผ ์ ๊ฑฐํ ๊ฒ์ด๋ค.
Debouncing is removing unwanted input noise from buttons, switches or other user input. Debouncing prevents extra activations or slow functions from triggering too often. Debouncing is used in hardware switches, programs and websites.
๋๋ฐ์ด์ค๋ ํ๋์จ์ด ์ฉ์ด๋ก ์์๋์๋ค.
๋ฒํผ, ์ค์์น ๋ฑ์์ ์์น์๋ ๋ ธ์ด์ฆ/๋ฐ์ด์ค๋ฅผ ์ ๊ฑฐํ๋ ๊ฒ์ด๋ผ๊ณ ํ ์ ์๋ค.
๊ทธ๋ผ ๋ฐ์ด์ค ์ ํธ๊ฐ ๋ฌด์์ธ๊ฐ? ์ฐ๋ฆฌ๊ฐ ์ ๊ธฐ๋ฅผ ์ผฐ๋ค ๋๋ ์ฌ์ฉํ๋ ์ค์ ๋ฌผ๋ฆฌ์ ์ธ ์ ๊ธฐ ์ค์์น๋ฅผ ์๋ก ๋ค๋ฉด, ์ค์์น๋ฅผ ๋๋ฅผ๋๋ง๋ค ์ ํธ๊ฐ ํ๋์ฒ๋ผ ๋ฐ์ํ๋ค.
์ฒ์ ์ค์์น๋ฅผ ๋๋ฅด๋ฉด ์ ํธ๋ ์ผ์ง์ ์ด ์๋ ๊ณ ์ ๊ณผ ์ ์ ์ ์ฌ๋ฌ๋ฒ ๋ฐ๋ณตํ๋ ํ๋๊ฐ์ ๋ชจ์์๋ฅผ ๊ฐ์ง๋ค๊ฐ ์ดํ์ ์์ ์ ์ธ ์ผ์ง์ ์ ์ฐพ๋๋ค. ์ด๋ฐ ์ ํธ๋ก ์ค์์น๋ฅผ on/off ํ๋ ๊ฒ์ ์ ์ดํ ์ ์๋๋ฐ, ์ ํธ๊ฐ ๊ณ ์ ์ ๋๋ฌํด์ผ์ง ์ค์์น๊ฐ ์ผ์ง๋ ๊ทธ ์ง์ ์ด ์ด๋ฅด๊ธฐ ์ ๊น์ง ์ด๊ธฐ์ ๋ฐ์ํ๋ ์ง์ง์ง๊ฑฐ๋ฆฌ๋ ํ๋๊ฐ์ ์ ํธ๊ฐ ์ฐ๋ฆฌ๊ฐ ์์น์๋ ๋ ธ์ด์ฆ์ด๊ณ , ๋๋ฐ์ด์ฑ์ด๋ผ๋ ๊ธฐ์ ๋ก ์ด ๋ฐ์ด์ค ์ ํธ๋ฅผ ๋ฌด์ํ๋ค.
์ ๋ฆฌํ์๋ฉด debouncing์ ํ๋์จ์ด์์ ์ ํธ๊ฐ ๋๋ฌด ๋ง์ด ํ์ฑํ/์คํ๋๋ ๋ ธ์ด์ฆ๋ฅผ ๋ง๋ ๊ธฐ๋ฒ์ธ๋ฐ, ์น ํ๋ก๊ทธ๋จ์์๋ ๋ง์ฐฌ๊ฐ์ง๋ก ์ ์ ์ ์ธํ์ ๋ฐ๋ฅธ ๊ณผ๋ํ ์ด๋ฒคํธ ํธ์ถ์ ์์ ๋ ๊ฐ๋ ์ด๋ค.
์น ํ๋ฐํธ์์์ ๋๋ฐ์ด์ค
์งง์ ์๊ฐ ๊ฐ๊ฒฉ์ผ๋ก ๋ฐ์ํ๋ ์ฐ์๋ ์ด๋ฒคํธ๊ฐ ์์ ๋, ์ฐ์๋ ์ด๋ฒคํธ๋ค(=๋ ธ์ด์ฆ)์ ํธ์ถํ์ง ์๋ค๊ฐ ์ผ์ ์๊ฐ์ด ๊ฒฝ๊ณผํ ์ดํ์ ํ ๋ฒ๋ง ํธ์ถํ๋ ๊ฐ๋ ์ ๋ปํ๋ค.
์ฆ, ์งง์ ์๊ฐ๋์ ์ฐ์ํด์ ๋ฐ์ํ ์ด๋ฒคํธ๋ฅผ ๊ทธ๋ฃน์ผ๋ก ๋ชจ์๋ค๊ฐ `์ผ์ ์๊ฐ ์ดํ์ ๋ง์ง๋ง ํ ๋ฒ๋ง ์ด๋ฒคํธ๋ฅผ ํธ์ถ`ํ๋ค.
์ฌ์ฉ ์์
- ๋ธ๋ผ์ฐ์ ํฌ๊ธฐ resize ์ด๋ฒคํธ
- ๋ฒํผ ์ค๋ณต ํด๋ฆญ ๋ฐฉ์ง ์ฒ๋ฆฌ
- ์ค์๊ฐ ๊ฒ์์ด ์๋์์ฑ input
๊ทธ๋ผ ๋๋ฐ์ด์ค์ ๊ฐ๋ ์ ๋ฆฌ์กํธ์์ ์ด๋ป๊ฒ ์ ์ฉํ ์ ์์๊น?
์๊ฐ ํ์ด๋จธ๋ฅผ ์ค์ ํ๋ ๊ฒ์ด ๊ด๊ฑด์ด ๋๋ค.
๋๋ฐ์ด์ค๋ผ๋ ํ ํฌ๋์ ์์์ ์ ๋ฆฌํ๋ ๊ฒ์ฒ๋ผ ์ผ์ ์๊ฐ ์ดํ์ ํ ๋ฒ๋ง ์ด๋ฒคํธ๋ฅผ ํธ์ถํ๋ค๋ ์ปจ์ ์ด๋ค. ๋ฐ๋ผ์ ๋ฆฌ์กํธ์์ ์ด ๊ฐ๋ ์ ์ฝ๋๋ก ๋ น์ด๋ ค๋ฉด? ์ ์ ๊ฐ input ์ ์ ๋ ฅํ๋ฉด ํ์ด๋จธ๋ฅผ ์ค์ ํด์ ์ง์ ํ ์๊ฐ ๊ฐ๊ฒฉ ์ด๋ด์ ๋ค์ด์ค๋ input์ ๊ฐ์ง๊ณ ์๋ค๊ฐ, ์ค์ ํ ์๊ฐ์ด ๋๋๋ฉด ๋๋ฐ์ด์ฑ๋ ๋ฐธ๋ฅ๊ฐ์ ์ํ๊ฐ์ผ๋ก ๊ด๋ฆฌํด์ ์ฌ์ฉํ๋ค.
์ด์ ๋๋ฐ์ด์ค์ํจ ์ธํ ๋ฐธ๋ฅ๋ฅผ ๋ฆฌํดํด์ฃผ๋ useDebounce๋ผ๋ custom hook์ ๋ง๋ค์ด ์ฃผ์๋ค.
useDebounce hook
export const useDebounce = (value: string, delay: number) => {
const [debounceValue, setDebounceValue] = useState(value);
useEffect(() => {
const debounceTimer = setTimeout(() => {
setDebounceValue(value);
}, delay);
return () => {
clearTimeout(debounceTimer);
};
}, [value, delay]);
return debouncedValue;
};
useDebounce๋ผ๋ ํจ์๋ค. ์ธ์๋ก 2๊ฐ์ง๋ฅผ ๋ฐ๋๋ฐ, ๋๋ฐ์ด์ฑ ์ฒ๋ฆฌ๋ฅผ ํ ๋ฐธ๋ฅ๊ฐ `value` ๊ณผ ์ค์ ํ๊ณ ์ถ์ ์๊ฐ ๊ฐ๊ฒฉ `delay` ์ ์ ํด์ค ์ ์๋ค. ์ด ํจ์๋ ๋ฐ์์จ ์ธ์๋ฅผ ๋๋ฐ์ด์ฑ ์ฒ๋ฆฌํด์ ์ค์ ํ ์๊ฐ์ด ๋๋๋ฉด ๊ทธ ๋ง์ง๋ง ์ธํ ๋ฐธ๋ฅ๊ฐ์ ์ ์ฅํ๊ณ , ์ด๋ฅผ `debouncedValue` ๋ผ๋ ๊ฐ์ผ๋ก ๋ฆฌํดํด์ค๋ค.
ํจ์์ ๋ด๋ถ๋ฅผ ๋ณด์.
์๋ฐ์คํฌ๋ฆฝํธ ๋ด์ฅํจ์ setTimeout ๋ฅผ ํ์ฉํด์ `delay` ์ธ์๋ก ๋ฐ์ ์๊ฐ ๋งํผ์ ์ฌ๋ ํ์ด๋จธ๋ฅผ ์ค์ ํ๋ค.
์ด ํ์ด๋จธ๋ฅผ ์ค์ ํ ์๊ฐ์ด ๋๋ฌ์ ๋ setTimeout ์์ ํจ์๊ฐ ํธ์ถ๋๋๋ฐ, ํ์ด๋จธ๊ฐ ๋๋์ผ `setDebounceValue`๋ผ๋ ๋๋ฐ์ด์ค ๋ฐธ๋ฅ๋ฅผ ์ํ๋ก ์ ์ฅํ๋ ๊ฒ์ด๋ค.
๋ํ ์ด ํ์ด๋จธ๊ฐ useEffect hook์ผ๋ก ๊ด๋ฆฌ๋๋ ๊ฒ์ ๋ณด๋ฉด ๋ณธ๋ value๋ก ๋๊ฒจ์ฃผ๋ input ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์๋ก ํ์ด๋จธ๊ฐ ์์๋๊ณ ํ์ด๋จธ๊ฐ ํด๋ฆฌ์ด ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค. ๊ฒฐ๊ตญ ์ ์ ๊ฐ ์ธํ์ ์น ๋๋ง๋ค ๋งค๋ฒ ํ์ด๋จธ๋ฅผ ์ฌ์ค์ ํ๋ค๋ ๊ฒ์ด๋ค. value๊ฐ์ด ๋ฐ๋๋ฉด ์ด์ ์ธํ ๊ฐ์ ์ค์ ํ ํ์ด๋จธ๋ฅผ ์ทจ์ํ๊ณ ๋ค์ ์๋ก์ด ์๊ฐ์ผ๋ก ํ์ด๋จธ๋ฅผ ๊ฐฑ์ ํ๋ค.
์ด๋ ๊ฒ ํจ์ผ๋ก์จ ๋ณธ๋ input๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์๋ก ํ์ด๋จธ๋ฅผ ๋ฑ๋กํ๊ณ ํ์ด๋จธ๊ฐ ์ข ๋ฃ๋ ๋ ๋๋ฐ์ด์ค๋ ๊ฐ์ ๊ฐ์ง ์ ์๋ค.
๊ฒ์ ์ปดํฌ๋ํธ์์ ์ฌ์ฉ
export const SearchAutoComplete = () => {
const debouncedSearchInputValue = useDebounce(searchInputValue, 1000);
useEffect(() => {
getLazySearchList(); //api ํธ์ถ
}, [debouncedSearchInputValue]);
return ํ
์คํธํ๋ ์ปดํฌ๋ํธ
}
์ปดํฌ๋ํธ์์ useEffect hook์ ์ฌ์ฉํด์ ๋๋ฐ์ด์ฑ๋ ์ธํ๋ฐธ๋ฅ๊ฐ์ด ๋ณํ ๋๋ง๋ค api ํธ์ถ์ ํ๋ค.
์ด์ ๊ทธ๋ผ input ๊ฐ์ด ํ ๊ธ์ ํ ๊ธ์ ๋ณํ ๋๋ง๋ค api๋ฅผ ํธ์ถํ๋ ๊ฒ์ด ์๋, ์ค์ ํ ์๊ฐ์ด ๋๋๋ฉด ํ ๋ฒ๋ง ํธ์ถ๋๋ ๋๋ฐ์ด์ฑ๋ ๋ฐธ๋ฅ๊ฐ์ด ๋ณํ ๋๋ง๋ค api๋ฅผ ํธ์ถํ๊ฒ ๋์ด ์ฑ๋ฅ์ ๊ฐ์ ํ ์ ์๋ค.
References
https://www.techtarget.com/whatis/definition/debouncing