๐Ÿ”ฅ React: ๋ฆฌ์•กํŠธ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ useCallback, React.memo, useMemo()

summereuna๐Ÿฅยท2022๋…„ 11์›” 24์ผ
0

React JS

๋ชฉ๋ก ๋ณด๊ธฐ
23/69

๋ฆฌ์•กํŠธ์—์„œ๋Š” state ํ˜น์€ props์ด ๋ณ€๊ฒฝ๋  ๊ฒฝ์šฐ ๋ฆฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•œ๋‹ค.

๋ถ€๋ชจ์˜ state๋ฅผ props์œผ๋กœ ๋ฐ›๋Š” ์ปดํฌ๋„ŒํŠธA์™€, ๋‹จ์ˆœํžˆ onClick()ํ•จ์ˆ˜๋ฅผ props์œผ๋กœ ๋ฐ›๋Š” ์ปดํฌ๋„ŒํŠธ B๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•˜์ž.

๋ถ€๋ชจ์˜ state๊ฐ€ ๋ฐ”๋€Œ๋ฉด ๋ถ€๋ชจ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์ž์‹ ์ปดํฌ๋„ŒํŠธ๋„ ํ•จ๊ป˜ ๋ฆฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•œ๋‹ค. ๋ณ€ํ•˜์ง€ ์•Š์€ onClick()ํ•จ์ˆ˜๋ฅผ props์œผ๋กœ ์ „๋‹ฌ ๋ฐ›๋Š” ์ปดํฌ๋„ŒํŠธ B๋„ ๋ฆฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•œ๋‹ค. ์ด๋Š” onClick()ํ•จ์ˆ˜์˜ ์ฐธ์กฐ ๊ฐ’์ด ๋‹ฌ๋ผ์ ธ์„œ ๋ฆฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•œ๋‹ค.

๐Ÿ“š ๋ฐ์ดํ„ฐ ์ž๋ฃŒ ๊ตฌ์กฐ

  • ์›์‹œํ˜•: String, Number, Boolean, undefine, null, ...
    • ์›์‹œ ์ž๋ฃŒํ˜•์ด ํ• ๋‹น๋  ๋•Œ์—๋Š” ๋ณ€์ˆ˜์— ๊ฐ’(value) ์ž์ฒด๊ฐ€ ๋‹ด๊ธด๋‹ค.
  • ์ฐธ์กฐํ˜•: Array, Object, Function
    • ์ฐธ์กฐ ์ž๋ฃŒํ˜•์ด ํ• ๋‹น๋  ๋•Œ๋Š” ๋ณด๊ด€ํ•จ์˜ ์ฃผ์†Œ(reference)๊ฐ€ ๋‹ด๊ธด๋‹ค.

useCallback

์ตœ์ ํ™”๋ฅผ ํ†ตํ•ด ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์„ ์ค„์—ฌ๋ณด์ž.
useCallback()์€ memoization ๊ธฐ๋Šฅ์œผ๋กœ ๊ธฐ์กด์— ์ˆ˜ํ–‰ํ•œ ์—ฐ์‚ฐ ๊ฐ’์„ ์ €์žฅํ•ด ๋‘๊ณ  ์žฌ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค€๋‹ค.

  • useCallback()์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ๊ฐ์‹ธ๋ฉด, ์˜์กด์„ฑ ๋ฐฐ์—ด(dependency)์ด ๋ณ€ํ•˜์ง€ ์•Š๋Š” ์ด์ƒ ์ปดํฌ๋„ŒํŠธ ๋ฆฌ๋ Œ๋”๋ง์‹œ ๋ณ€์ˆ˜์— ๋™์ผํ•œ ํ•จ์ˆ˜๊ฐ€ ํ• ๋‹น๋˜์–ด ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์ด ์ค„์–ด๋“ ๋‹ค.

๋ฆฌ์•กํŠธ๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋  ๋•Œ ๋‘ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์น˜๋Š”๋ฐ, ์ฒซ ๋ฒˆ์งธ๋กœ Render Phase(๋ Œ๋” ๋‹จ๊ณ„)๋ฅผ ๊ฑฐ์น˜๊ณ  ๋‘ ๋ฒˆ์งธ๋กœ Commit Phase(์ปค๋ฐ‹ ๋‹จ๊ณ„)๋ฅผ ๊ฑฐ์นœ๋‹ค.

  • Render Phase
    ์ปดํฌ๋„ŒํŠธ(ํ•จ์ˆ˜)๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋ฆฌ์•กํŠธ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ณผ์ •์—์„œ virtual DOM์„ ๋งŒ๋“œ๋Š”๋ฐ, ์ด์ „ DOM๊ณผ ๋น„๊ตํ•˜์—ฌ DOM์„ ์žฌ์กฐ์„ฑ(Reconciliation)ํ•˜๋Š” ๋‹จ๊ณ„์ด๋‹ค.
  • Commit Phase
    Redner Phase์—์„œ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„์ด ํ™•์ธ ๋œ ๊ฒฝ์šฐ, ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„์„ Real DOM์— ๋ฐ˜์˜ํ•˜๋Š” ๋‹จ๊ณ„์ด๋‹ค. ๋”ฐ๋ผ์„œ Render Phase์—์„œ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„์ด ์—†๋‹ค๊ณ  ํ™•์ธ๋œ ๊ฒฝ์šฐ ์ปค๋ฐ‹๋‹จ๊ณ„๋Š” ์ƒ๋žต๋œ๋‹ค.

๊ฒฐ๋ก ์ ์œผ๋กœ, useCallback()์„ ์‚ฌ์šฉํ•œ ๊ฒฐ๊ณผ ๊ฐ’์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์–ด ์ปดํฌ๋„ŒํŠธB์˜ render phase๋Š” ์‹คํ–‰๋˜์—ˆ์ง€๋งŒ, commit phase๋Š” ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ์œ ์˜๋ฏธํ•œ ํšจ๊ณผ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค.

React.memo

๊ทธ๋Ÿฐ๋ฐ ์—ฌ์ „ํžˆ render phase๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์ด ๊ณ„์† ๋ฐœ์ƒํ•œ๋‹ค. ์™œ ๊ทธ๋Ÿด๊นŒ?
๋ฆฌ์•กํŠธ์˜ ์ปดํŒŒ์ผ๋Ÿฌ๋ฅผ ์—ด์–ด๋ณด๋ฉด React.createElement๋กœ ์—ฌ์ „ํžˆ ์ปดํฌ๋„ŒํŠธB๋ฅผ ๋งŒ๋“ค๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

render phase ๋„ ๋ง‰๊ธฐ ์œ„ํ•ด์„œ๋Š” React.memo๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
React.memo๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ „๋‹ฌ๋ฐ›์€ props๋ฅผ ์ด์ „ props์™€ ๋น„๊ตํ•˜์—ฌ ๊ฐ™์œผ๋ฉด ๋ฆฌ๋ Œ๋”๋ง์„ ๋ง‰์•„์ฃผ๊ณ , ๋ Œ๋”๋ง ๊ฒฐ๊ณผ๋ฅผ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์ด ๋•Œ, ๋ฆฌ์•กํŠธ ๋ฉ”๋ชจ ๊ธฐ๋Šฅ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ props์„ ์–•์€ ๋น„๊ต๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๊ตํ•œ๋‹ค.

    ์–•์€ ๋น„๊ต

    • ์›์‹œํƒ€์ž…: ๊ฐ’์ด ๋‹ค๋ฅธ์ง€ ๋น„๊ต
    • ์ฐธ์กฐํƒ€์ž…: ์ฐธ์กฐ ๊ฐ’์ด ๊ฐ™์€์ง€ ๋น„๊ต
function ์ปดํฌ๋„ŒํŠธB({์˜จํด๋ฆญํ•จ์ˆ˜}){
  return <div>
    {์˜จํด๋ฆญํ•จ์ˆ˜}
    </div>
}
export default React.memo(์ปดํฌ๋„ŒํŠธB);
  • ์ด๋ ‡๊ฒŒ ์ปดํฌ๋„ŒํŠธB๋ฅผ ๋ฆฌ์•กํŠธ๋ฉ”๋ชจ๋กœ ๊ฐ์‹ธ์ฃผ๋ฉด props์ด ๋ณ€ํ•˜์ง€ ์•Š๋Š” ํ•œ, ๋ฆฌ๋ Œ๋”๋ง์„ ๋ง‰์•„ render phase์ž์ฒด๋„ ๋ง‰์„ ์ˆ˜ ์žˆ๋‹ค.

useMemo()

props๋กœ ํ•จ์ˆ˜๋ง๊ณ  ๊ฐ์ฒด๋ฅผ ๋„˜๊ฒจ์ฃผ๋ฉด ์–ด๋–ป๊ฒŒ ๋ ๊นŒ?
์ปดํฌ๋„ŒํŠธB๋ฅผ ๋ฆฌ์•กํŠธ ๋ฉ”๋ชจ๋กœ ๊ฐ์‹ผ ์ฑ„, props์— ์˜จํด๋ฆญํ•จ์ˆ˜ ๋Œ€์‹  ๋ณ€ํ•˜์ง€ ์•Š๋Š” item์ด๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ๋ณด๋‚ด๋ณด์ž.

//App.js
const item = {
  name: "outer",
  number: 100,
}
//...
return (
  <์ปดํฌ๋„ŒํŠธB item={item} />
)
//์ปดํฌ๋„ŒํŠธB.js
function ์ปดํฌ๋„ŒํŠธB({item}){
  return(
    //...
  )
}

export default React.memo(์ปดํฌ๋„ŒํŠธB);

์ด ๊ฒฝ์šฐ, React.memo()๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Œ์—๋„ ์ปดํฌ๋„ŒํŠธB๊ฐ€ ๋ฆฌ๋ Œ๋”๋ง ๋œ๋‹ค.
์ปดํฌ๋„ŒํŠธ ์ž…์žฅ์—์„œ๋Š” ๋ถ€๋ชจ๋กœ ๋ถ€ํ„ฐ ๋งค๋ฒˆ ๋‹ค๋ฅธ item์„ ์ „๋‹ฌ๋ฐ›๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

item ์ด๋ผ๋Š” ๊ฐ์ฒด๊ฐ€ ๋งค๋ฒˆ ์ƒˆ๋กœ ์ƒ์„ฑ๋จ ๐Ÿ‘‰ ์ปดํฌ๋„ŒํŠธ์—๊ฒŒ ๋งค๋ฒˆ ๋‹ค๋ฅธ ์ฐธ์กฐ๊ฐ’์„ ๊ฐ€์ง„ item์„ props์œผ๋กœ ์ „๋‹ฌ ๐Ÿ‘‰ React.memo() ์ž‘๋™ํ•˜์ง€ ์•Š์Œ

์ด๋Ÿด ๋•Œ๋Š” useMemo() ํ›…์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

  • useCallback()
    ํ•จ์ˆ˜์— ๋Œ€ํ•œ memoization ์ œ๊ณต
  • useMemo()
    ๊ฐ’์— ๋Œ€ํ•œ memoization ์ œ๊ณต
    ์˜์กด์„ฑ ๋ฐฐ์—ด์ด ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ์ด์ƒ, ๋ฆฌ๋ ˆ๋Ÿฐ๋”๋ง์‹œ ๊ฐ™์€ ๊ฐ’ ๋ฐ˜ํ™˜ํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง ์—†์•ฐ
const memoizedItem = useMemo(() => item, []);

useMemo()ํ›…์„ ์‚ฌ์šฉํ•ด memoized๋œ item์„ ๋งŒ๋“ค์–ด ์ปดํฌ๋„ŒํŠธB์— props์œผ๋กœ ๋ณด๋‚ด๋ฉด item๊ณผ ๋™์ผํ•œ ๊ฐ์ฒด๊ฐ€ ์ „๋‹ฌ๋˜๋ฏ€๋กœ ๋ฆฌ์•กํŠธ๋ฉ”๋ชจ๊ฐ€ ์ •์ƒ์ ์œผ๋กœ ์ž‘๋™ํ•˜์—ฌ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค.

๊ฒฐ๋ก 

๋ฌด์ž‘์ • ์‚ฌ์šฉํ•˜๊ธฐ ๋ณด๋‹ค ๋จผ์ € ๊ทผ๋ณธ์ ์ธ ์ฝ”๋“œ ๊ฐœ์„ ์ด ๊ฐ€๋Šฅํ•œ์ง€ ๊ณ ๋ฏผํ•ด ๋ณผ๊ฒƒ!

๋ฏธ๋ฆฌ ์ตœ์ ํ™” ํ•˜๋ ค๊ณ  ํ•˜์ง€ ๋ง๊ณ , ํ•„์š”ํ•  ๋•Œ ์‚ฌ์šฉํ•  ๊ฒƒ!

์ฐธ๊ณ 

profile
Always have hope๐Ÿ€ & constant passion๐Ÿ”ฅ

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