๐Ÿ’ป Frontend

Debounce์™€ Throttle

category
๐Ÿ’ป Frontend

Debounce vs Throttle

์„œ๋น„์Šค์—์„œ ์žฆ์€ ๋ฆฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•œ๋‹ค๋ฉด ์„ฑ๋Šฅ ์ €ํ•˜์˜ ์›์ธ์ด ๋ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์žฆ์€ ๋ฆฌ๋ Œ๋”๋ง์˜ ๋ฌธ์ œ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
  1. ์„ฑ๋Šฅ ์ €ํ•˜: ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ์žฌ๋ Œ๋”๋ง๋˜๋ฉด ์„ฑ๋Šฅ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ์ปดํฌ๋„ŒํŠธ ๊ณ„์ธต ๊ตฌ์กฐ๊ฐ€ ๊นŠ๊ฑฐ๋‚˜ ๋ณต์žกํ•œ ๊ฒฝ์šฐ์— ์žฆ์€ ๋ฆฌ๋ Œ๋”๋ง์€ ์„ฑ๋Šฅ์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ์ด ๋” ์ปค์ง‘๋‹ˆ๋‹ค.
  1. ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ์š”์ฒญ: ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง๋˜๋ฉด ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ ๋‚ด์˜ ๋ฐ์ดํ„ฐ ์š”์ฒญ๋„ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์€ ๋”ฐ๋ผ์„œ ๋ถˆํ•„์š”ํ•œ ๋ฐ์ดํ„ฐ ์š”์ฒญ์„ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  1. ์ปดํฌ๋„ŒํŠธ state ์†์‹ค: ์žฆ์€ ๋ฆฌ๋ Œ๋”๋ง์œผ๋กœ ์ธํ•ด ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ(state)๊ฐ€ ์˜ˆ์ƒ์น˜ ๋ชปํ•˜๊ฒŒ ์žƒ์–ด๋ฒ„๋ฆด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‹ˆ ์žฆ์€ ๋ฆฌ๋ Œ๋”๋ง์„ ํ•˜๋ฉด ์•ˆ๋ฉ๋‹ˆ๋‹ค.
์ด๋ฒคํŠธ ํ˜ธ์ถœ๋„ ์˜ˆ์™ธ๋Š” ์•„๋‹™๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ๋ฐœ์ƒํ• ๋•Œ ๊ด€๋ จ ์ฝœ๋ฐฑ ์ด๋ฒคํŠธ ํ•จ์ˆ˜๋ฅผ ์ž์ฃผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ์„ฑ๋Šฅ ์ €ํ•˜์˜ ์›์ธ์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ํด๋ฆญ์ด๋ฒคํŠธ์ฒ˜๋Ÿผ ๋‹จ์ˆœํ•˜์ง€ ์•Š๊ณ  ํ‚ค๋ณด๋“œ์˜ ์ž…๋ ฅ์ด ์ง€์†์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ์Šคํฌ๋กค ์ด๋ฒคํŠธ๊ฐ€ ์ƒ๊ธฐ๋ฉด (ํŠนํžˆ, ์Šคํฌ๋กค ์ด๋ฒคํŠธ) ํ•œ๋ฒˆ์˜ ๋งˆ์šฐ์Šค ๋กค๋ง์œผ๋กœ๋„ ๋ช‡์‹ญ-๋ช‡๋ฐฑ๋ฒˆ์˜ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•ด๋ฒ„๋ฆฝ๋‹ˆ๋‹ค.
๋งŒ์•ฝ, ์ด๋Ÿฐ ์ด๋ฒคํŠธ๊ฐ€ ์ผ์–ด๋‚ ๋•Œ๋งˆ๋‹ค api์š”์ฒญ์„ ๋ณด๋‚ด๊ฒŒ ๋œ๋‹ค๋ฉด ์„œ๋ฒ„ ๊ณผ๋ถ€ํ•˜๊ฐ€ ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์œ ์˜๋ฏธํ•œ ์‹œ์ ์— ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์•„๋ž˜ ๋‘ ๊ฐœ๋…์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
ย 

Debounce

์—ฐ์ด์€ ์ด๋ฒคํŠธ ์ค‘ ๋งˆ์ง€๋ง‰ ์ด๋ฒคํŠธ๋งŒ ์ธ์‹ํ•œ๋‹ค.
๋””๋ฐ”์šด์Šค๋ฅผ ์ ์šฉํ•˜๊ธฐ ์ข‹์€ ์˜ˆ์ œ๋Š” ๋ฐ”๋กœ ๊ฒ€์ƒ‰ ์ž…๋ ฅ ์ด๋ฒคํŠธ์ž…๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ๋“ค์–ด ๊ฒ€์ƒ‰์ฐฝ์— โ€˜์œ ์‹œ์˜จโ€™์„ ์ž…๋ ฅํ•  ๊ฒฝ์šฐ ๋ชจ๋“  ์ž…๋ ฅ์— ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ฒƒ์ด ์•„๋‹Œ ์ž…๋ ฅ์ด ๋งˆ๋ฌด๋ฆฌ ๋˜์—ˆ์„ ๋•Œ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋งŒ์•ฝ ๋””๋ฐ”์šด์Šค๊ฐ€ ์ ์šฉ์ด ์•ˆ๋˜์–ด์žˆ๋‹ค๋ฉด ๋ฌด์˜๋ฏธ์•ˆ ๋‹จ์–ด์—๋„ ๋ถˆํ•„์š”ํ•œ ์š”์ฒญ์„ ๋ณด๋‚ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ex. ใ…‡, ์œ ใ……, ์œ ์‹œ์˜ค, ์œ ์‹œ์˜จ
ย 

Debounce ๊ตฌํ˜„

function SearchInput() { const [query, setQuery] = useState(''); const [tmpQuery, setTmpQuery] = useState(query); const handleChange = (e: ChangeEvent<HTMLInputElement>) => setTmpQuery(e.target.value); useEffect(() => { const debounce = setTimeout(() => { return setQuery(tmpQuery); }, 300); //->setTimeout ์„ค์ • return () => clearTimeout(debounce); //->clearTimeout ๋ฐ”๋กœ ํƒ€์ด๋จธ ์ œ๊ฑฐ }, [tmpQuery]); //->๊ฒฐ๊ตญ ๋งˆ์ง€๋ง‰ ์ด๋ฒคํŠธ์—๋งŒ setTimeout์ด ์‹คํ–‰๋จ return ( <> <SearchInputBlock> <div className='search-Input'> <SearchIcon /> <input value={tmpQuery} onChange={handleChange} /> </div> </SearchInputBlock> <SearchResult query={query} /> </> ); }
์ฃผ์š” ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.
useEffect(() => { const debounce = setTimeout(() => { return setQuery(tmpQuery); }, 300); //->setTimeout ์„ค์ • return () => clearTimeout(debounce); //->clearTimeout ๋ฐ”๋กœ ํƒ€์ด๋จธ ์ œ๊ฑฐ }, [tmpQuery]); //->๊ฒฐ๊ตญ ๋งˆ์ง€๋ง‰ ์ด๋ฒคํŠธ์—๋งŒ setTimeout์ด ์‹คํ–‰๋จ
  1. useEffect์—์„œ tmpQuery์˜ ๋ณ€๊ฒฝ์„ ๊ฐ์ง€ํ•œ๋‹ค. tmpQuery๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ๋‚ด๋ถ€ ์ฝ”๋“œ ๋ธ”๋ก์ด ์‹คํ–‰๋œ๋‹ค.
  1. setTimeout ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ 300ms ํ›„์— ์‹คํ–‰๋˜๋Š” ํƒ€์ด๋จธ๋ฅผ ์„ค์ •ํ•œ๋‹ค. ์ด ํƒ€์ด๋จธ๋Š” setQuery(tmpQuery); ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
    1. ์ด๋•Œ, tmpQuery๋Š” useEffect์˜ ์˜์กด์„ฑ ๋ฐฐ์—ด์— ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ, tmpQuery๊ฐ€ ๋ณ€๊ฒจ๋ ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ํƒ€์ด๋จธ๊ฐ€ ์„ค์ •๋œ๋‹ค.
    2. ๋งˆ์ง€๋ง‰ ๋ณ€๊ฒฝ๋œ tmpQuery์— ๋Œ€ํ•œ setQuery๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
  1. useEffect์˜ ๋ฐ˜ํ™˜๋ฌธ์—์„œ๋Š” ์ด์ „ ํƒ€์ด๋จธ๊ฐ€ ์กด์žฌํ•˜๋ฉด(clearTimeout) ๊ทธ ํƒ€์ด๋จธ๋ฅผ ์ทจ์†Œํ•œ๋‹ค. ์ด๋กœ์จ ์ด์ „์— ์„ค์ •๋œ ํƒ€์ด๋จธ๋Š” ์‹คํ–‰๋˜์ง€ ์•Š๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
โ‡’ ๋”ฐ๋ผ์„œ, ์—ฐ์†์ ์œผ๋กœ tmpQuery๊ฐ€ ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„, ๋งˆ์ง€๋ง‰ ๋ณ€๊ฒฝ ์ดํ›„ 300ms๊ฐ€ ์ง€๋‚œ ํ›„์—setQuery(tmpQuery)๊ฐ€ ์‹คํ–‰๋˜๋ฏ€๋กœ, ๋งˆ์ง€๋ง‰ ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋งŒ ๋ณด์žฅ๋ฉ๋‹ˆ๋‹ค.
ย 
๋งจ ์ฒ˜์Œ ๋ถˆํ•„์š”ํ•œ ๋‹จ์–ด๋Š” ์š”์ฒญ์„ ํ•˜์ง€ ์•Š๊ณ , ๋งˆ์ง€๋ง‰ ์š”์ฒญ ์ดํ›„ 0.3์ดˆ๋ฅผ ๊ธฐ๋‹ค๋ฆฐ ๋‹ค์Œ ์•Œ๋งž์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.
ย 
ย 

Debounce โ†’ Throttle

๋””๋ฐ”์šด์Šค๋ฅผ ์ ์šฉํ•œ ์˜ˆ์ œ๋ฅผ ์“ฐ๋กœํ‹€๋ง์œผ๋กœ ๋ฐ”๊พธ์–ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์ฃผ์š”์ฝ”๋“œ๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ฐ”๊พธ์—ˆ์Šต๋‹ˆ๋‹ค.
const [throttle, setThrottle] = useState<boolean>(false); useEffect(() => { if (throttle) return; if (!throttle) { setThrottle(true); setTimeout(async () => { setSearchValue(tmpValue); setThrottle(false); }, 300); } }, [tmpValue]);
์ž…๋ ฅํ•  ๋•Œ ๋งˆ๋‹ค ์•„๋ž˜ ๋ฆฌ์ŠคํŠธ๊ฐ€ ๊นœ๋นก๊ฑฐ๋ฆฌ๋Š” ํ˜„์ƒ์„ ํ™•์ธํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ž…๋ ฅ ์ด๋ฒคํŠธ๋ฅผ ์“ฐ๋กœํ‹€๋ง์œผ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค๋ฉด ํฐ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. 0.3์ดˆ ๊ฐ„๊ฒฉ์œผ๋กœ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ง€ํ•˜๋Š”๋ฐ ์ž…๋ ฅ ๊ฐ’์„ โ€˜์ดใ……โ€™์œผ๋กœ ์ธ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž…๋ ฅ์„ โ€˜์ด์Šน์ œโ€™๋ผ๊ณ  ํ–ˆ์–ด๋„ ์ฐฐ๋‚˜์˜ ์ˆœ๊ฐ„์œผ๋กœ tmpValue๋ฅผ ์ด์ƒํ•œ ๊ฐ’์œผ๋กœ ์ธ์ง€ํ•˜์—ฌ ์‚ฌ์šฉ์ž๋Š” ์›ํ•˜์ง€ ์•Š๋Š” ํ™”๋ฉด์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ย 

Throttle

์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ ์„œ ์ผ์ • ์ฃผ๊ธฐ๋งˆ๋‹ค ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒ๋˜๋„๋ก ํ•œ๋‹ค. (์ผ์ •์ฃผ๊ธฐ๊ฐ€ ๋๋‚˜์ง€ ์•Š์œผ๋ฉด ์ด๋ฒคํŠธ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š”๋‹ค.)
์“ฐ๋กœํ‹€๋ง์„ ์ ์šฉํ•˜๊ธฐ ์ข‹์€ ์˜ˆ์ œ๋Š” ๋ฐ”๋กœ ์Šคํฌ๋กค์ด๋‚˜ ํŽ˜์ด์ง€ resize ์ด๋ฒคํŠธ์ž…๋‹ˆ๋‹ค.
๋งŒ์•ฝ ์Šคํฌ๋กค ์ด๋ฒคํŠธ์— ํฐ ์—ฐ์‚ฐ ์ด๋ฒคํŠธ ํ•จ์ˆ˜๊ฐ€ ์žˆ๋Š”๋ฐ ํŽ˜์ด์ง€๋ฅผ ์œ„์—์„œ ์•„๋ž˜๋กœ ํ•œ๊บผ๋ฒˆ์— ์Šคํฌ๋กค ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ด…์‹œ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ๋ชจ๋“  ์ดˆ๋งˆ๋‹ค ์Šคํฌ๋กค ์ด๋ฒคํŠธ๊ฐ€ ํ˜ธ์ถœ๋˜์–ด์„œ ์„œ๋น„์Šค ์„ฑ๋Šฅ ์ €ํ•˜์˜ ์›์ธ์ด ๋ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์Šคํฌ๋กค์„ 1์ดˆ๋™์•ˆํ• ๋•Œ ๊ณ„์† ์ด๋ฒคํŠธ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹Œ ํŠน์ • ์‹œ๊ฐ„๋งˆ๋‹ค ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒ๋˜๋Š” ์“ฐ๋กœํ‹€๋ง์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ย 

Throttle ๊ตฌํ˜„

export default function useGetWindowScrollHeight() { const [windowScrollHeight, setWindowScrollHeight] = useState<number>(0); let throttling = false; function onScroll() { if (throttling) return; throttling = true; setTimeout(() => { setWindowScrollHeight(window.scrollY); throttling = false; }, 200); } useEffect(() => { setWindowScrollHeight(window.scrollY); window.addEventListener('scroll', onScroll, { passive: true }); return () => { window.removeEventListener('scroll', onScroll); }; }, []); return windowScrollHeight; }
์ฃผ์š” ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.
let throttling = false; function onScroll() { if (throttling) return; throttling = true; setTimeout(() => { setWindowScrollHeight(window.scrollY); throttling = false; }, 200); }
  1. throttling ๊ฐ’์ด true์ผ ๋•Œ๋Š” ์ด๋ฒคํŠธ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  1. 0.2์ดˆ ๊ฐ„๊ฒฉ์œผ๋กœ throttling๊ฐ’์ด ๋ฐ”๋€๋‹ค.
  1. ๊ทธ๋ž˜์„œ 0.2์ดˆ ๋งˆ๋‹ค ์ด๋ฒคํŠธ๊ฐ€ ํ˜ธ์ถœ๋œ๋‹ค.
ย 

Throttle โ†’ Debounce

์•„๋ž˜ ํ™”๋ฉด์€ ์Šคํฌ๋กค ํ• ๋•Œ๋งˆ๋‹ค 0.3์ดˆ์”ฉ ์ด๋ฒคํŠธ๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ๋งŒ์•ฝ ์“ฐ๋กœํ‹€๋ง์„ ๋””๋ฐ”์šด์Šค๋กœ ๋ฐ”๊พธ๊ฒŒ ๋œ๋‹ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ์š”?
notion image
๋””๋ฐ”์šด์Šค๋ฅผ ์ ์šฉํ•œ๋‹ค๋ฉด ์Šคํฌ๋กค์„ ํ•˜๊ณ  ์Šคํฌ๋กค์ด ๋ฉˆ์ถœ ๋•Œ ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ์Šคํฌ๋กค ํ•˜๋Š” ๊ณผ์ •์—์„œ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋ณด์ง€ ๋ชปํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์ค‘๊ฐ„ ์ค‘๊ฐ„ ์ด๋ฒคํŠธ๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ๋˜๋Š” ์ƒํ™ฉ(ex. ์Šคํฌ๋กค ์ด๋ฒคํŠธ)์—์„œ๋Š” ์“ฐ๋กœํ‹€๋ง์„ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์ข‹์„ ๊ฒƒ ์ž…๋‹ˆ๋‹ค.
ย 

๋งˆ๋ฌด๋ฆฌ

Debounce์™€ throttle๋ฅผ ํ”„๋กœ์ ํŠธ์— ์ ์šฉ์‹œํ‚จ๋‹ค๋ฉด ์‚ฌ์†Œํ•˜์ง€๋งŒ ํ”„๋กœ์ ํŠธ์˜ ์„ฑ๋Šฅ์„ ๋†’์ด๊ณ  ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‘ ๊ธฐ๋ฒ• ์ค‘ ์–ด๋– ํ•œ ๊ฒƒ์„ ์ ์šฉ์‹œํ‚ค๋Š”๊ฒŒ ์ข‹์„ ์ง€ ๊ณ ๋ฏผํ•ด๋ณด์‹œ๊ณ  ํ•ด๋‹น ๊ธ€์ด ๋„์›€๋˜์…จ๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค!
ย 

References

[React] ๋ธŒ๋ผ์šฐ์ € ํฌ๊ธฐ ๊ฐ์ง€, throttle, debounce
๋ฐ”๋กœ ์ง์ „ ํฌ์ŠคํŒ…์—์„œ antd ๊ทธ๋ฆฌ๋“œ๋ฅผ ์ด์šฉํ•ด์„œ ๋ธŒ๋ผ์šฐ์ € ํ™”๋ฉด ์‚ฌ์ด์ฆˆ์— ๋”ฐ๋ผ ๋ฐ˜์‘ํ•˜๋Š” ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค์–ด ๋ณด์•˜๋‹ค. ์ •ํ™•ํžˆ 768px์— ๋ฐ”๋€Œ๋Š”์ง€ ๋ณด๋ ค๊ณ  ํ˜„์žฌ ํ™”๋ฉด์˜ ๋„ˆ๋น„๋ฅผ ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ์— ๋„์›Œ์ฃผ๋ ค๊ณ  ํ•œ๋‹ค. 1. resize ์ด๋ฒคํŠธ resize ์ด๋ฒคํŠธ๋Š” document view์˜ ํฌ๊ธฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ ๋ฐœ์ƒํ•œ๋‹ค. ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๋งˆ๋‹ค width state์— ๋ธŒ๋ผ์šฐ์ €์˜ ๋„ˆ๋น„๊ฐ€ ์ €์žฅ๋˜๋„๋ก ํ–ˆ๋‹ค. useEffect๋ฅผ ์ด์šฉํ•ด์„œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋งˆ์šดํŠธ ๋  ๋•Œ ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•œ๋‹ค. const [width, setWidth] = useState(window.innerWidth); const handleResize = () => { setWidth(window.innerWidth); }; useEffect(() => { windo..
[React] ๋ธŒ๋ผ์šฐ์ € ํฌ๊ธฐ ๊ฐ์ง€, throttle, debounce