๐Ÿง  useCallback์œผ๋กœ ๋ถˆํ•„์š”ํ•œ ๋ Œ๋”๋ง ์ œ๊ฑฐํ•˜๊ธฐ

zizonyoungjunยท2024๋…„ 12์›” 31์ผ
12
post-thumbnail

๋ถˆํ•„์š”ํ•œ ์žฌ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•˜๋Š” ๊ฑด React ์„ฑ๋Šฅ ์ตœ์ ํ™”์˜ ์ฃผ์š” ๊ณผ์ œ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์—…๋ฐ์ดํŠธ๋  ๋•Œ, ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์˜๋„์น˜ ์•Š๊ฒŒ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๋Š” ๋ฌธ์ œ๋Š” ํ”„๋ก ํŠธ์—”๋“œ ๊ฐœ๋ฐœ์—์„œ์˜ ์ฃผ๋œ ๋ถˆ์ฒญ๊ฐ์ด์ฃ . ๊ฐ€๋ น, ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ์™€ ๊ฐ™์ด ๋ Œ๋”๋ง๋งˆ๋‹ค ์ƒˆ๋กœ ์ƒ์„ฑ๋˜๋Š” ํ•จ์ˆ˜๊ฐ€ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌ๋˜๋ฉด, React๋Š” ํ•ด๋‹น ์ฐธ์กฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ๋‹ค๊ณ  ํŒ๋‹จํ•ด ๋ถˆํ•„์š”ํ•œ ์ž‘์—…์„ ๋ฐ˜๋ณตํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค๐Ÿ‘ท๐Ÿปโ€โ™‚๏ธ โ›๏ธ

์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋“ฑ์žฅํ•œ ๋„๊ตฌ๊ฐ€ ๋ฐ”๋กœ useCallback์ž…๋‹ˆ๋‹ค. useCallback์€ ํŠน์ • ํ•จ์ˆ˜์˜ ์ฐธ์กฐ๋ฅผ ๊ณ ์ •ํ•˜์—ฌ, ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๋„๋ก ์ œํ•œํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ปดํฌ๋„ŒํŠธ ๊ฐ„ props ์ „๋‹ฌ ๊ณผ์ •์—์„œ ๋ถˆํ•„์š”ํ•œ ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•˜๊ณ , ์„ฑ๋Šฅ ์ตœ์ ํ™”๋ฅผ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ useCallback์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋Œ€๊ฐ€๊ฐ€ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ๋‚จ์šฉํ•˜์ง€ ์•Š๊ณ  ์ ์žฌ์ ์†Œ์— ํ™œ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์ ์ ˆํ•˜์ง€ ์•Š์€ ์ƒํ™ฉ์—์„œ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ์—” ์˜คํžˆ๋ ค ๋ฉ”๋ชจ๋ฆฌ ๋ถ€๋‹ด์„ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ๋ถ€๋ฉ”๋ž‘์ด ๋˜์–ด ๋Œ์•„์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿชƒ๐Ÿ’ฅ

์ด๋ฒˆ ํฌ์ŠคํŠธ์—์„œ๋Š” useCallback์˜ ์›๋ฆฌ์™€ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ํ†ตํ•ด React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋”์šฑ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

๋ฉ”๋ชจ์ด์ œ์ด์…˜๊ณผ useCallback

React์—์„œ useCallback์€ ๋ฉ”๋ชจ์ด์ œ์ด์…˜(Memoization)์„ ํ†ตํ•ด ํ•จ์ˆ˜ ์ฐธ์กฐ๋ฅผ ๊ณ ์ •ํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ์žฌ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ๋™์ผํ•œ ์ž…๋ ฅ์— ๋Œ€ํ•ด ์ด์ „ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๊ณ , ๋™์ผํ•œ ์ž…๋ ฅ์ด ๋‹ค์‹œ ์ œ๊ณต๋  ๊ฒฝ์šฐ ์ €์žฅ๋œ ๊ฒฐ๊ณผ๋ฅผ ์žฌํ™œ์šฉํ•˜๋Š” ์ตœ์ ํ™” ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ณต์žกํ•œ ๊ณ„์‚ฐ์ด ํฌํ•จ๋œ ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜๋ณต์ ์œผ๋กœ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ, ๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ๋ถˆํ•„์š”ํ•œ ์—ฐ์‚ฐ์„ ์ค„์ž„์œผ๋กœ์จ ์ฒ˜๋ฆฌ ์‹œ๊ฐ„์„ ๋‹จ์ถ•ํ•ฉ๋‹ˆ๋‹ค.

React์—์„œ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ํŠนํžˆ ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง๊ณผ ๊ด€๋ จ๋œ ํ•จ์ˆ˜ ์ฐธ์กฐ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์œผ๋กœ React๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋  ๋•Œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ํ•จ์ˆ˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์—์„œ ์ƒˆ๋กœ์šด ์ž…๋ ฅ์ด ์—†๋”๋ผ๋„ ๋™์ผํ•œ ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ƒ์„ฑ๋˜๋ฉด ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ๋Š”๋ฐ์š”, ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋กœ useCallback์ž…๋‹ˆ๋‹ค.

useCallback์€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ• ๊นŒ?

useCallback์€ ํ•จ์ˆ˜ ์ฐธ์กฐ๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•˜์—ฌ, ์˜์กด์„ฑ ๋ฐฐ์—ด์— ํฌํ•จ๋œ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ํ•œ ๋™์ผํ•œ ์ฐธ์กฐ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด React๋Š” ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๋”๋ผ๋„ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌ๋œ ํ•จ์ˆ˜์˜ ์ฐธ์กฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜์Œ์„ ๊ฐ์ง€ํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ์žฌ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.

const handleClick = useCallback(() => {
  console.log("ํด๋ฆญ !");
}, []); // ์˜์กด์„ฑ ๋ฐฐ์—ด์ด ๋น„์–ด ์žˆ์–ด ํ•จ์ˆ˜ ์ฐธ์กฐ๊ฐ€ ๊ณ ์ •๋จ

์œ„ ์ฝ”๋“œ์—์„œ handleClick ํ•จ์ˆ˜๋Š” useCallback์„ ํ†ตํ•ด ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋˜๋ฏ€๋กœ, ์˜์กด์„ฑ ๋ฐฐ์—ด์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ํ•œ ๋™์ผํ•œ ์ฐธ์กฐ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๊ฐ€ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌ๋˜๋ฉด, ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง ์—ฌ๋ถ€์™€ ๊ด€๊ณ„์—†์ด ์ž์‹์€ ๊ธฐ์กด ์ฐธ์กฐ๋ฅผ ์œ ์ง€ํ•˜์—ฌ ๋ Œ๋”๋ง์ด ๋ถˆํ•„์š”ํ•˜๊ฒŒ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

useCallback์˜ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์ด ์ค‘์š”ํ•œ ์ด์œ 

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

useCallback์€ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋  ๋•Œ๋„ ๋™์ผํ•œ ํ•จ์ˆ˜ ์ฐธ์กฐ๋ฅผ ์ž์‹์— ์ „๋‹ฌํ•˜๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ๋ถ€๋ชจ์™€ ์ž์‹ ๊ฐ„์˜ ๋ณต์žกํ•œ props ์ „๋‹ฌ ๊ตฌ์กฐ๋‚˜ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๊ฐ€ ํฌํ•จ๋œ ์ƒํ™ฉ์—์„œ ๊ทธ ํšจ๊ณผ๊ฐ€ ๋‘๋“œ๋Ÿฌ์ง‘๋‹ˆ๋‹ค. ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋Š” ์ „๋‹ฌ๋ฐ›์€ props๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•˜์„ ๋•Œ ๋ Œ๋”๋ง์„ ์ƒ๋žตํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋™์ผํ•œ ํ•จ์ˆ˜ ์ฐธ์กฐ๋ฅผ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์„ฑ๋Šฅ ์ตœ์ ํ™”์˜ ํ•ต์‹ฌ์ด ๋ฉ๋‹ˆ๋‹ค.

useCallback ์‚ฌ์šฉ์˜ ์œ ์˜์ 

์ด๋ ‡๋“ฏ useCallback์€ ํ•จ์ˆ˜ ์ฐธ์กฐ๋ฅผ ๊ณ ์ •ํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ์žฌ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•˜๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฉ”๋ชจ์ด์ œ์ด์…˜์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ถ”๊ฐ€๋กœ ์†Œ๋น„ํ•˜๋ฉฐ, ์ž˜๋ชป๋œ ์‚ฌ์šฉ์€ ์„ฑ๋Šฅ ์ €ํ•˜๋‚˜ ์ฝ”๋“œ ๋ณต์žก์„ฑ ์ฆ๊ฐ€๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๋•Œ๋ฌธ์— ์ผ๋ถ€ ๊ฐœ๋ฐœ์ž๋“ค์€ ์‚ฌ์šฉ์„ ๊บผ๋ฆฌ๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋”๋Ÿฌ ์žˆ์ฃ  ๐Ÿ™…๐Ÿป ์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„œ๋Š” useCallback์ด ์ ์ ˆํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์™€, ์‚ฌ์šฉ ์‹œ ์œ ์˜ํ•ด์•ผ ํ•  ์ ์„ ๋‹ค๋ฃจ์–ด๋ณด๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค.

๋‹จ์ˆœํ•œ ์ปดํฌ๋„ŒํŠธ์—์„œ์˜ ๋ถˆํ•„์š”ํ•œ ์‚ฌ์šฉ

๋‚ด๋ถ€์ ์œผ๋กœ๋งŒ ์‚ฌ์šฉ๋˜๋Š” ํ•จ์ˆ˜์— useCallback์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ๋Œ€๋ถ€๋ถ„ ๋ถˆํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ํ•จ์ˆ˜๊ฐ€ ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ์ „๋‹ฌ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ๋ Œ๋”๋ง ์‹œ๋งˆ๋‹ค ์ƒˆ๋กœ ์ƒ์„ฑ๋˜๋”๋ผ๋„ ์„ฑ๋Šฅ์— ์‹ค์งˆ์ ์ธ ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

function Counter() {
  const [count, setCount] = useState(0);

  const increment = () => {
    setCount((prev) => prev + 1);
  };

  return <button onClick={increment}>๋ˆŒ๋Ÿฌ๋ณด์†Œ</button>;
}

์œ„ ์ฝ”๋“œ์—์„œ increment ํ•จ์ˆ˜๋Š” ์ปดํฌ๋„ŒํŠธ ๋‚ด๋ถ€์—์„œ๋งŒ ์‚ฌ์šฉ๋˜๋ฉฐ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ƒํ™ฉ์—์„œ useCallback์„ ์‚ฌ์šฉํ•˜๋ฉด ํ•จ์ˆ˜ ์ฐธ์กฐ๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ํ•˜๋Š๋ผ ์˜คํžˆ๋ ค ๋ฉ”๋ชจ๋ฆฌ์™€ CPU ์ž์›์„ ๋‚ญ๋น„ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

๋ Œ๋”๋ง ๋น„์šฉ์ด ๋‚ฎ์€ ์ปดํฌ๋„ŒํŠธ

์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง์ด ๋‹จ์ˆœํ•˜๋‹ค๋ฉด, useCallback์œผ๋กœ ํ•จ์ˆ˜ ์ฐธ์กฐ๋ฅผ ๊ณ ์ •ํ•˜๋”๋ผ๋„ ์–ป๋Š” ์ด์ ์ด ๊ฑฐ์˜ ์—†์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹จ์ˆœํžˆ ๋ฒ„ํŠผ์ด๋‚˜ ํ…์ŠคํŠธ ์š”์†Œ๋ฅผ ๋ Œ๋”๋งํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋Š” ๋ Œ๋”๋ง ์ž์ฒด์˜ ๋น„์šฉ์ด ๋งค์šฐ ๋‚ฎ๊ธฐ ๋•Œ๋ฌธ์—, ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์˜ ์žฌ๋ Œ๋”๋ง์— ๋”ฐ๋ผ ๋‹ค์‹œ ๋ Œ๋”๋ง๋˜๋”๋ผ๋„ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์— ๊ฑฐ์˜ ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

function SimpleButton({ onClick }) {
  return <button onClick={onClick}>Click me</button>;
}

์ด ๊ฒฝ์šฐ, useCallback์œผ๋กœ props๋ฅผ ๊ณ ์ •ํ•˜๋”๋ผ๋„ ๋ Œ๋”๋ง ์„ฑ๋Šฅ์˜ ์ฐจ์ด๋ฅผ ์ฒด๊ฐํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๋“ฏ ๋ Œ๋”๋ง ๋น„์šฉ์ด ๋‚ฎ์€ ์ปดํฌ๋„ŒํŠธ๋Š” ์ฝ”๋“œ์˜ ๋‹จ์ˆœ์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์€ ์„ ํƒ์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜์กด์„ฑ ๊ด€๋ฆฌ์˜ ๋ณต์žก์„ฑ

useCallback์„ ์‚ฌ์šฉํ•  ๋•Œ ์˜์กด์„ฑ ๋ฐฐ์—ด์€ ํ•จ์ˆ˜ ์ฐธ์กฐ์˜ ์—…๋ฐ์ดํŠธ ์กฐ๊ฑด์„ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฐฐ์—ด์ด ์ž˜๋ชป ์„ค์ •๋˜๋ฉด, ์ƒํƒœ ๋ณ€๊ฒฝ์ด ์ œ๋Œ€๋กœ ๋ฐ˜์˜๋˜์ง€ ์•Š๊ฑฐ๋‚˜ ๋ถˆํ•„์š”ํ•œ ์—…๋ฐ์ดํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์˜์กด์„ฑ ๋ฐฐ์—ด์„ ๋น„์›Œ๋‘๋ฉด ์ƒํƒœ๋‚˜ props ๋ณ€๊ฒฝ์ด ํ•จ์ˆ˜์— ๋ฐ˜์˜๋˜์ง€ ์•Š์•„ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ๋™์ž‘์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const handleClick = useCallback(() => {
  console.log(count); // ์ด ์ฝ”๋“œ๋Š” ์ตœ์‹  ์ƒํƒœ๋ฅผ ์ฐธ์กฐํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Œ
}, []); // ์˜์กด์„ฑ ๋ฐฐ์—ด์— count๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ์•Š์Œ

์œ„ ์ฝ”๋“œ์—์„œ๋Š” count๊ฐ€ ์˜์กด์„ฑ ๋ฐฐ์—ด์— ํฌํ•จ๋˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์—, handleClick ํ•จ์ˆ˜๋Š” ๋ Œ๋”๋ง ์‹œ์ ์˜ ์ดˆ๊ธฐ count ๊ฐ’์„ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋”๋ผ๋„ ์ตœ์‹  ๊ฐ’์„ ๋ฐ˜์˜ํ•˜์ง€ ์•Š๋Š” ์˜ค๋ฅ˜๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜์กด์„ฑ ๋ฐฐ์—ด์— ํ•„์š”ํ•œ ๊ฐ’์„ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ถ”๊ฐ€ํ•  ๊ฐ’์ด ๋งŽ์•„์ง€๋ฉด ๋ฐฐ์—ด ๊ด€๋ฆฌ๊ฐ€ ๋ณต์žกํ•ด์ง€๊ณ  ์ฝ”๋“œ ๊ฐ€๋…์„ฑ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ useCallback์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์˜์กด์„ฑ ๋ฐฐ์—ด์˜ ์„ค์ •์ด ํ•จ์ˆ˜์˜ ์˜๋„์™€ ์ผ์น˜ํ•˜๋Š”์ง€ ํ•ญ์ƒ ์‹ ์ค‘ํžˆ ๊ฒ€ํ† ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€๋ฒผ์šด ํ•จ์ˆ˜ ๋กœ์ง

useCallback์€ ๋ณต์žกํ•˜๊ฑฐ๋‚˜ ๋ฐ˜๋ณต์ ์ธ ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜์—์„œ ํšจ๊ณผ์ ์ด์ง€๋งŒ, ๋กœ์ง์ด ๋‹จ์ˆœํ•œ ํ•จ์ˆ˜์—์„œ๋Š” ์˜คํžˆ๋ ค ๋น„์šฉ์ด ๋” ์ปค์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ฝ˜์†” ๋กœ๊ทธ๋ฅผ ์ถœ๋ ฅํ•˜๊ฑฐ๋‚˜ ๊ฐ„๋‹จํ•œ ๊ฐ’ ๋ณ€๊ฒฝ๋งŒ ์ˆ˜ํ–‰ํ•˜๋Š” ํ•จ์ˆ˜๋ผ๋ฉด ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ์ž์ฒด๊ฐ€ ๋น„์šฉ์ด ๋” ํด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const logMessage = useCallback(() => {
  console.log("๋ฐฉ๊ฐ€๋ฐฉ๊ฐ€");
}, []);

์œ„ ์ฝ”๋“œ์—์„œ logMessage ํ•จ์ˆ˜๋Š” ๋‹จ์ˆœํžˆ ์ฝ˜์†” ๋กœ๊ทธ๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ, ๋ฉ”๋ชจ์ด์ œ์ด์…˜์„ ์œ„ํ•ด ์ถ”๊ฐ€์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์†Œ๋น„ํ•˜๊ณ  ์˜์กด์„ฑ์„ ๊ด€๋ฆฌํ•ด์•ผ ํ•˜๋Š” ๋น„์šฉ์ด ํ•จ์ˆ˜ ์ƒ์„ฑ ๋น„์šฉ๋ณด๋‹ค ๋” ํด ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•จ์ˆ˜ ์‹คํ–‰ ์‹œ๊ฐ„์ด 1ms ์ดํ•˜๋กœ ์ธก์ •๋˜๊ฑฐ๋‚˜, ๋ฐ˜๋ณต ํ˜ธ์ถœ์ด ์„ฑ๋Šฅ์— ํฐ ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š” ์ƒํ™ฉ์—์„œ๋Š” useCallback์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ํŽธ์ด ๋” ์ ์ ˆํ•ฉ๋‹ˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์ด๋Ÿฌํ•œ ์ƒํ™ฉ์—์„œ๋Š” ์–ด๋–ค ๋Œ€์•ˆ์ด ์žˆ์„๊นŒ์š”?๐Ÿ’ก

์šฐ์„ , ๋‹จ์ˆœํ•œ ํ•จ์ˆ˜๋‚˜ ๋ Œ๋”๋ง ๋น„์šฉ์ด ๋‚ฎ์€ ์ปดํฌ๋„ŒํŠธ์—์„œ๋Š” useCallback์„ ์™„์ „ํžˆ ์ƒ๋žตํ•˜๊ณ  React์˜ ๊ธฐ๋ณธ ๋ Œ๋”๋ง ํ๋ฆ„์— ๋งก๊ธฐ๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค. React๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋งค์šฐ ํšจ์œจ์ ์ธ ๋ Œ๋”๋ง ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ œ๊ณตํ•˜๋ฉฐ, ๋‹จ์ˆœํ•œ ์ž‘์—…์—์„œ๋Š” ์ตœ์ ํ™”๋ณด๋‹ค ์ฝ”๋“œ ๊ฐ€๋…์„ฑ๊ณผ ์œ ์ง€๋ณด์ˆ˜์„ฑ์„ ์šฐ์„ ์‹œํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

๋˜ํ•œ, ์˜์กด์„ฑ ๊ด€๋ฆฌ๊ฐ€ ๋ณต์žกํ•œ ์ƒํ™ฉ์—์„œ๋Š” ํ•จ์ˆ˜ ์ฐธ์กฐ๋ฅผ ๊ณ ์ •ํ•˜๊ธฐ๋ณด๋‹ค๋Š” ํ•ด๋‹น ๋กœ์ง์„ ๋ณ„๋„์˜ ํ›…์ด๋‚˜ Context๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ์˜์กด์„ฑ์„ ๋ช…์‹œ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ๋„ ์ข‹์€ ์ ‘๊ทผ๋ฒ•์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, React Context๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ƒํƒœ์™€ ๋กœ์ง์„ ์ „์—ญ์ ์œผ๋กœ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ์–ด props ๋“œ๋ฆด๋ง ์—†์ด๋„ ๊ฐ„๊ฒฐํ•œ ์ฝ”๋“œ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

const CounterContext = React.createContext();

function CounterProvider({ children }) {
  const [count, setCount] = useState(0);

  const increment = () => setCount((prev) => prev + 1);

  return (
    <CounterContext.Provider value={{ count, increment }}>
      {children}
    </CounterContext.Provider>
  );
}

function CounterButton() {
  const { increment } = useContext(CounterContext);
  return <button onClick={increment}>ํด๋ฆญ !</button>;
}

์œ„ ์˜ˆ์ œ์—์„œ increment๋Š” Context๋ฅผ ํ†ตํ•ด ๊ด€๋ฆฌ๋˜๋ฏ€๋กœ, ์˜์กด์„ฑ ๋ฐฐ์—ด ์„ค์ •์˜ ๋ถ€๋‹ด ์—†์ด ์ฐธ์กฐ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๋ก ์ ์œผ๋กœ, useCallback์€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉํ•˜๊ณ , ๋Œ€์•ˆ์ด ๋” ๋‚˜์€ ์„ ํƒ์ผ ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์—์„œ๋Š” ๊ณผ๊ฐํžˆ ์ƒ๋žตํ•˜๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ์ตœ์ ํ™” ๋ฐฉ๋ฒ•์„ ๊ณ ๋ คํ•˜๋Š” ๊ฒƒ์ด ๋” ๋‚˜์€ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

useCallback์˜ ์‚ฌ์šฉ ์‚ฌ๋ก€

์ด๋ ‡๋“ฏ ์‚ฌ์šฉ์— ์‹ ์ค‘ํ•ด์•ผํ•˜๋Š” useCallback์ด์ง€๋งŒ, ์ ์ ˆํ•œ ๋งฅ๋ฝ์—์„œ ํ™œ์šฉํ•œ๋‹ค๋ฉด useCallback์€ React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ ์ตœ์ ํ™”์— ํฐ ๋„์›€์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋ น ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ, API ํ˜ธ์ถœ, ์ƒํƒœ ๊ด€๋ฆฌ ๋“ฑ ๋‹ค์–‘ํ•œ ์ƒํ™ฉ์—์„œ ํšจ๊ณผ์ ์œผ๋กœ ํ™œ์šฉ๋  ์ˆ˜ ์žˆ๋Š”๋ฐ์š”. ์ด๋ฒˆ ์ฑ•ํ„ฐ์—์„œ๋Š” useCallback์„ ๋ฐ”ํƒ•์œผ๋กœ ์ตœ์ ํ™”๋ฅผ ์ด๋ฃฐ ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ๋Œ€ํ‘œ์ ์ธ ์‚ฌ๋ก€๋ฅผ ๋‹ค๋ค„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ์ตœ์ ํ™”

useCallback์€ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๊ฐ€ React.memo๋กœ ๊ฐ์‹ธ์ ธ ์žˆ๊ณ , ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ž์‹์—๊ฒŒ ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ๋ฅผ ์ „๋‹ฌํ•ด์•ผ ํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. React.memo๋Š” ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ์—์„œ ์ „๋‹ฌ๋˜๋Š” props๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ํ•œ, ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ•จ์ˆ˜๋Š” JavaScript์—์„œ ์ฐธ์กฐํ˜• ๋ฐ์ดํ„ฐ์ด๋ฏ€๋กœ, ๋ Œ๋”๋ง ์‹œ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋˜๋Š”๋ฐ์š”. ์ด๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— ๋ถˆํ•„์š”ํ•œ ๋ Œ๋”๋ง์„ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

function Parent() {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    setCount((prev) => prev + 1);
  }, []);

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>๋ˆŒ๋Ÿฌ๋ณด์†Œ</button>
      <Child onClick={handleClick} />
    </div>
  );
}

const Child = React.memo(({ onClick }) => {
  return <button onClick={onClick}>๋ˆŒ๋Ÿฌ๋ด์œ </button>;
});

์œ„ ์ฝ”๋“œ์—์„œ handleClick ํ•จ์ˆ˜๋Š” useCallback์„ ํ†ตํ•ด ์ฐธ์กฐ๊ฐ€ ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ Œ๋”๋ง๋  ๋•Œ handleClick์˜ ์ฐธ์กฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ, React.memo๋กœ ๊ฐ์‹ธ์ง„ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋Š” ๋ Œ๋”๋ง๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ถˆํ•„์š”ํ•œ ์—ฐ์‚ฐ์„ ์ค„์ด๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

API ํ˜ธ์ถœ ์ตœ์ ํ™”

useCallback์€ API ํ˜ธ์ถœ์„ ๊ด€๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜์—์„œ๋„ ํฐ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. API ํ˜ธ์ถœ ํ•จ์ˆ˜๊ฐ€ ์ƒˆ๋กœ ์ƒ์„ฑ๋˜๋ฉด, ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์˜์กด์„ฑ ๋ฐฐ์—ด์— ํฌํ•จํ•œ useEffect๊ฐ€ ๋ถˆํ•„์š”ํ•˜๊ฒŒ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋™์ผํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ์š”์ฒญํ•˜๊ฑฐ๋‚˜, ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ์„ ์ฆ๊ฐ€์‹œํ‚ฌ ์œ„ํ—˜์„ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.

function Fetcher() {
  const fetchData = useCallback(async (endpoint) => {
    const response = await fetch(endpoint);
    const data = await response.json();
    console.log(data);
  }, []);

  useEffect(() => {
    fetchData('/api/data');
  }, [fetchData]);

  return <div>๋ฐ์ดํ„ฐ fetch ์ค‘ ...</div>;
}

์œ„ ์ฝ”๋“œ์—์„œ fetchData๋Š” useCallback์„ ํ†ตํ•ด ์ฐธ์กฐ๊ฐ€ ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด useEffect์˜ ์˜์กด์„ฑ ๋ฐฐ์—ด์ด ๋ถˆํ•„์š”ํ•œ ์—…๋ฐ์ดํŠธ๋กœ ์ธํ•ด ๋ฐ˜๋ณต ์‹คํ–‰๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŠนํžˆ, API ํ˜ธ์ถœ์ด ๋นˆ๋ฒˆํ•˜๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์ด ์ค‘์š”ํ•œ ๊ฒฝ์šฐ, ์ด ์ ‘๊ทผ ๋ฐฉ์‹์€ ๋ถˆํ•„์š”ํ•œ ํ˜ธ์ถœ์„ ๋ฐฉ์ง€ํ•˜๊ณ  ์•ˆ์ •์„ฑ์„ ํ™•๋ณดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ƒํƒœ ๊ด€๋ฆฌ์™€ Reducer ์ตœ์ ํ™”

์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•œ useReducer ํ›…์„ ์‚ฌ์šฉํ•  ๋•Œ, dispatch ํ•จ์ˆ˜์™€ ํ•จ๊ป˜ ๋ณต์žกํ•œ ์•ก์…˜์„ ์ฒ˜๋ฆฌํ•ด์•ผ ํ•  ๊ฒฝ์šฐ useCallback์€ ์ƒํƒœ ์—…๋ฐ์ดํŠธ ๋กœ์ง์˜ ์ฐธ์กฐ๋ฅผ ๊ณ ์ •ํ•˜๋Š” ๋ฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ƒํƒœ ์—…๋ฐ์ดํŠธ ํ•จ์ˆ˜๊ฐ€ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌ๋  ๋•Œ ์ฐธ์กฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์•„ ๋ถˆํ•„์š”ํ•œ ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

function Counter() {
  const [state, dispatch] = useReducer((state, action) => {
    switch (action.type) {
      case 'increment':
        return { count: state.count + 1 };
      default:
        return state;
    }
  }, { count: 0 });

  const increment = useCallback(() => {
    dispatch({ type: 'increment' });
  }, [dispatch]);

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={increment}>๋ˆŒ๋Ÿฌ๋ดฅ</button>
    </div>
  );
}

์—ฌ๊ธฐ์„œ increment ํ•จ์ˆ˜๋Š” useCallback์œผ๋กœ ๋ฉ”๋ชจ์ด์ œ์ด์…˜๋˜์–ด dispatch์™€ ํ•จ๊ป˜ ์ฐธ์กฐ๊ฐ€ ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด, ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ์ž์‹ ์ปดํฌ๋„ŒํŠธ์— increment๋ฅผ props๋กœ ์ „๋‹ฌํ•˜๋”๋ผ๋„ ์ฐธ์กฐ๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์œผ๋ฉฐ, ์ž์‹ ์ปดํฌ๋„ŒํŠธ์˜ ๋ถˆํ•„์š”ํ•œ ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋งˆ๋ฌด๋ฆฌํ•˜๋ฉฐ

React ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์„ฑ๋Šฅ ์ตœ์ ํ™”๋Š” ๋‹จ์ˆœํžˆ ๋ Œ๋”๋ง ์†๋„๋ฅผ ๋†’์ด๋Š” ๋ฌธ์ œ๋ฅผ ๋„˜์–ด, ๋™์ž‘์˜ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ณ  ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๋ฐ ์ค‘์š”ํ•œ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. useCallback์€ ์ด๋Ÿฌํ•œ ์ตœ์ ํ™”์—์„œ ํ•ต์‹ฌ์ ์ธ ๋„๊ตฌ๋กœ, ์ฐธ์กฐ ๊ณ ์ •์„ ํ†ตํ•ด ๋ถˆํ•„์š”ํ•œ ์žฌ๋ Œ๋”๋ง์„ ๋ฐฉ์ง€ํ•˜๊ณ , ๋ณต์žกํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ๋„ ์•ˆ์ •์ ์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ๋•์Šต๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ useCallback์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐ์—๋Š” ๋ถ„๋ช…ํ•œ ๊ธฐ์ค€๊ณผ ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ž˜๋ชป๋œ ์‚ฌ์šฉ์€ ๋ฉ”๋ชจ๋ฆฌ ์†Œ๋น„์™€ ์ฝ”๋“œ ๋ณต์žก์„ฑ์„ ์ฆ๊ฐ€์‹œํ‚ฌ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ด๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ๋ฐ˜๋“œ์‹œ ์˜์กด์„ฑ ๋ฐฐ์—ด๊ณผ ํ•จ์ˆ˜ ์ฐธ์กฐ์˜ ์˜ํ–ฅ์„ ์‹ ์ค‘ํžˆ ๊ฒ€ํ† ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ์„ฑ๋Šฅ ์ตœ์ ํ™”์˜ ํšจ๊ณผ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฒ€์ฆํ•˜๋Š” ๊ณผ์ •๋„ ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค.

ํ•˜์ง€๋งŒ ์ด๋Š” useCallback ์ž์ฒด์˜ ๋ฌธ์ œ๊ฐ€ ์•„๋‹ˆ๋ผ, ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฅผ ์–ด๋–ค ๋งฅ๋ฝ์—์„œ ์–ด๋–ป๊ฒŒ ์ ์šฉํ–ˆ๋Š๋ƒ์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง€๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ์ ์ ˆํ•œ ์‚ฌ์šฉ ์กฐ๊ฑด๊ณผ ๋ช…ํ™•ํ•œ ๋ชฉ์ ์ด ์žˆ๋‹ค๋ฉด, useCallback์€ ์—ฌ์ „ํžˆ ์„ฑ๋Šฅ ์ตœ์ ํ™”์˜ ํ›Œ๋ฅญํ•œ ๋„๊ตฌ๊ฐ€ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค ๐Ÿ› ๏ธ

์ด๋ฒˆ ์•„ํ‹ฐํด์—์„œ๋Š” useCallback์˜ ์›๋ฆฌ์™€ ์œ ์˜์ , ๊ทธ๋ฆฌ๊ณ  ํšจ๊ณผ์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€๋ฅผ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ด ๋„๊ตฌ๊ฐ€ ๊ฐ€์ง„ ๊ฐ€๋Šฅ์„ฑ๊ณผ ํ•œ๊ณ„๋ฅผ ๋ช…ํ™•ํžˆ ์ดํ•ดํ•˜๊ณ , ์ ์žฌ์ ์†Œ์— ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค. useCallback, ์ด์   ๋„ˆ๋ฌด ๋ฏธ์›Œํ•˜์ง€ ๋งˆ์„ธ์š” ~! โค๏ธโ€๐Ÿฉน

1๊ฐœ์˜ ๋Œ“๊ธ€

comment-user-thumbnail
2025๋…„ 1์›” 2์ผ

์„ธ๋‚˜ํ›…ใ„ทใ„ท

๋‹ต๊ธ€ ๋‹ฌ๊ธฐ

๊ด€๋ จ ์ฑ„์šฉ ์ •๋ณด