πŸͺ useMemo(), useCallBack()

지은·2022λ…„ 11μ›” 25일
0

βš›οΈ React

λͺ©λ‘ 보기
12/23

λ Œλ”λ§ μ΅œμ ν™”, μ»΄ν¬λ„ŒνŠΈ μ΅œμ ν™”λ₯Ό μœ„ν•œ Hook으둜 useMemo(), useCallBack()이 μžˆλ‹€.

useMemoκ°€ μ–Έμ œ ν•„μš”ν• κΉŒ?

μ•„λž˜μ˜ μ½”λ“œμ—μ„œ calculate() λŠ” λ³΅μž‘ν•œ 연산을 ν•΄μ•Όν•˜λŠ” ν•¨μˆ˜μ΄κ³ , 값을 λ°˜ν™˜ν•˜λŠ” 데 λͺ‡ 초 이상이 κ±Έλ¦°λ‹€κ³  κ°€μ •ν•΄λ³΄μž.

λŒ€λΆ€λΆ„μ˜ React μ»΄ν¬λ„ŒνŠΈλŠ” state와 props의 λ³€ν™”λ‘œ 인해 μˆ˜λ§Žμ€ λ Œλ”λ§μ„ κ±°μΉ˜λŠ”λ°,
μ΄λ•Œ, μ»΄ν¬λ„ŒνŠΈκ°€ λ Œλ”λ§λœλ‹€λŠ” 것은 ν•¨μˆ˜ λ‚΄λΆ€μ˜ λͺ¨λ“  λ³€μˆ˜κ°€ μ΄ˆκΈ°ν™”λœλ‹€λŠ” 것을 μ˜λ―Έν•œλ‹€.

κ·Έλ ‡λ‹€λ©΄ Calculator μ»΄ν¬λ„ŒνŠΈλŠ” λ Œλ”λ§λ  λ•Œλ§ˆλ‹€ calculate() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜κ³ , λ³€μˆ˜ result에 값을 ν• λ‹Ήν•΄μ£ΌλŠ” 것을 맀번 μˆ˜ν–‰ν•œλ‹€λŠ” 것을 μ˜λ―Έν•œλ‹€.
즉, μ»΄ν¬λ„ŒνŠΈ λ Œλ”λ§μ΄ λ°œμƒν•  λ•Œλ§ˆλ‹€ 맀번 λͺ‡ 초 μ΄μƒμ˜ μ‹œκ°„μ΄ μ†Œμš”λ  것이고, μ΄λŠ” 맀우 λΉ„νš¨μœ¨μ μ΄λ‹€.

function Calculator({ value }) {   // props둜 valueλ₯Ό λ°›λŠ”λ‹€.
  const result = calculate(value); // 맀우 λ³΅μž‘ν•œ 연산을 μˆ˜ν–‰ν•˜λŠ” ν•¨μˆ˜
  
  return (
    <>
      <div>{result}</div>
    </>
  );
}

➑️ μ΄λ•Œ, useMemo() Hook을 μ‚¬μš©ν•˜λ©΄, 이전에 κ΅¬μΆ•λœ λ Œλ”λ§κ³Ό μƒˆλ‘­κ²Œ κ΅¬μΆ•λœ λ Œλ”λ§μ„ λΉ„κ΅ν•˜μ—¬ value 값이 동일할 경우, 연산을 또 λ‹€μ‹œ μˆ˜ν–‰ν•˜μ§€ μ•Šκ³  이전 λ Œλ”λ§μ˜ value 값을 κ·ΈλŒ€λ‘œ ν™œμš©ν•  수 있게 ν•œλ‹€.

  • useMemo()λŠ” λ©”λͺ¨μ΄μ œμ΄μ…˜(Memoization) κ°œλ…μ„ ν™œμš©ν•΄ λ³΅μž‘ν•œ μ—°μ‚°μ˜ 쀑볡을 ν”Όν•˜κ³  React μ•±μ˜ μ„±λŠ₯을 μ΅œμ ν™”μ‹œν‚¨λ‹€.
  • 직접 λ©”λͺ¨μ΄μ œμ΄μ…˜ κ°œλ…μ„ μ΄μš©ν•΄ λ‘œμ§μ„ κ΅¬ν˜„ν•΄λ„ λ˜μ§€λ§Œ, useMemo() Hook을 ν˜ΈμΆœν•΄ μ΄μš©ν•˜λ©΄ 훨씬 κ°„νŽΈν•˜λ‹€.

λ©”λͺ¨μ΄μ œμ΄μ…˜(Memoization)

: 기쑴에 μˆ˜ν–‰ν•œ μ—°μ‚°μ˜ 결과값을 λ©”λͺ¨λ¦¬μ— μ €μž₯해두고, λ™μΌν•œ μž…λ ₯이 λ“€μ–΄μ˜€λ©΄ μž¬ν™œμš©ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ° 기법

λ©”λͺ¨μ΄μ œμ΄μ…˜μ„ 적절히 ν™œμš©ν•˜λ©΄, 쀑볡 연산을 ν•  ν•„μš”κ°€ 없어지기 λ•Œλ¬Έμ— μ•±μ˜ μ„±λŠ₯을 μ΅œμ ν™”ν•  수 μžˆλ‹€.


useMemo()

: λ©”λͺ¨μ΄μ œμ΄μ…˜λœ 값을 λ°˜ν™˜ν•˜λŠ” Hook

useMemo(() => {}, []) : 첫 번째 인자둜 콜백 ν•¨μˆ˜, 두 번째 인자둜 쒅속성 배열을 κ°–λŠ”λ‹€.

1. ν•¨μˆ˜

콜백 ν•¨μˆ˜λŠ” λ©”λͺ¨μ΄μ œμ΄μ…˜ν•  값을 λ¦¬ν„΄ν•΄μ£ΌλŠ” ν•¨μˆ˜μ΄λ©°,
이 ν•¨μˆ˜κ°€ λ¦¬ν„΄ν•˜λŠ” 값이 곧 useMemo()κ°€ λ¦¬ν„΄ν•΄μ£ΌλŠ” 값이 λœλ‹€.

2. 쒅속성 λ°°μ—΄(dependency array)

useMemo()λŠ” 쒅속성 λ°°μ—΄ μ•ˆμ— μžˆλŠ” μš”μ†Œμ˜ 값이 μ—…λ°μ΄νŠΈλ  λ•Œλ§Œ 콜백 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜κ³ , λ©”λͺ¨μ΄μ œμ΄μ…˜λœ 값을 μ—…λ°μ΄νŠΈ ν•œλ‹€.

  • λ§Œμ•½ 빈 배열이라면, 맨 처음 μ»΄ν¬λ„ŒνŠΈκ°€ λ§ˆμš΄νŠΈλ˜μ—ˆμ„ λ•Œλ§Œ 값을 μ €μž₯ν•˜κ³ , μ΄ν›„μ—λŠ” 항상 λ©”λͺ¨μ΄μ œμ΄μ…˜λœ 값을 κΊΌλ‚΄μ™€μ„œ μ‚¬μš©ν•œλ‹€.
  • 배열이 μ—†λŠ” 경우, 맀 λ Œλ”λ§λ§ˆλ‹€ μƒˆλ‘œμš΄ 값을 κ³„μ‚°ν•œλ‹€.
import { useMemo } from "react";

function Calculator({ value }) {
  const result = useMemo(() => calculate(value), [value]);
  // μ»΄ν¬λ„ŒνŠΈκ°€ λ¦¬λ Œλ”λ§λ˜μ–΄λ„, value값이 λ™μΌν•˜λ‹€λ©΄ 연산을 μˆ˜ν–‰ν•˜μ§€ μ•Šκ³  이전 값을 κ·ΈλŒ€λ‘œ μ‚¬μš©ν•œλ‹€.
  
  return (
    <>
      <div>{result}</div>
    </>
  );
}

예제)

μ•„λž˜ μ½”λ“œμ—μ„œ μ½˜μ†”μ°½μ„ μ—΄κ³  μ•„λž˜ 계산기와 상관 μ—†λŠ” λ²„νŠΌμ„ 클릭해보면,
μ»΄ν¬λ„ŒνŠΈ 전체 λ¦¬λ Œλ”λ§μ΄ μΌμ–΄λ‚˜λ©° λΆˆν•„μš”ν•˜κ²Œ add() ν•¨μˆ˜κ°€ μ‹€ν–‰λ˜λŠ” 것을 λ³Ό 수 μžˆλ‹€.

⬇️
add() ν•¨μˆ˜μ— useMemo()λ₯Ό μ‚¬μš©ν•΄λ³΄λ©΄...
μ•„λž˜ 계산기와 상관 μ—†λŠ” λ²„νŠΌμ„ λˆŒλŸ¬μ„œ μ»΄ν¬λ„ŒνŠΈ 전체 λ¦¬λ Œλ”λ§μ΄ μΌμ–΄λ‚˜λ”λΌλ„, val1, val2값이 μ—…λ°μ΄νŠΈ λ˜μ§€ μ•Šμ•˜μœΌλ―€λ‘œ add() ν•¨μˆ˜λŠ” μ‹€ν–‰λ˜μ§€ μ•ŠλŠ”λ‹€. πŸ‘


useMemo()λŠ” 콜백 ν•¨μˆ˜κ°€ λ¦¬ν„΄ν•œ 값을 λ©”λͺ¨μ΄μ œμ΄μ…˜ν•˜λŠ” Hook이라면, useCallback()은 콜백 ν•¨μˆ˜ 자체λ₯Ό λ©”λͺ¨μ΄μ œμ΄μ…˜ν•˜λŠ” Hook이닀.

useCallback()

: λ©”λͺ¨μ΄μ œμ΄μ…˜λœ μ½œλ°±μ„ λ°˜ν™˜ν•˜λŠ” Hook

useCallback(() => {}, []) : 첫 번째 인자둜 콜백 ν•¨μˆ˜, 두 번째 인자둜 쒅속성 배열을 κ°–λŠ”λ‹€.

1. ν•¨μˆ˜

μ•žμ„œ Reactμ—μ„œ μ»΄ν¬λ„ŒνŠΈκ°€ λ Œλ”λ§λœλ‹€λŠ” 것은 ν•¨μˆ˜ λ‚΄λΆ€μ˜ λͺ¨λ“  λ³€μˆ˜κ°€ μ΄ˆκΈ°ν™”λ˜λŠ” 것이라고 μ„€λͺ…ν–ˆλ‹€.
JavaScriptμ—μ„œ ν•¨μˆ˜λŠ” 객체의 ν•œ μ’…λ₯˜λ‘œ, ν•¨μˆ˜κ°€ 객체이기 λ•Œλ¬Έμ— λ³€μˆ˜μ— ν• λ‹Ήν•  수 μžˆλŠ” 것이닀.

μ•„λž˜μ˜ μ½”λ“œμ—μ„œ λ§Œμ•½ μ»΄ν¬λ„ŒνŠΈ λ¦¬λ Œλ”λ§μ΄ λ°œμƒν•˜λ©΄, doubleμ΄λΌλŠ” λ³€μˆ˜μ— ν• λ‹Ήλœ ν•¨μˆ˜ 객체 λ˜ν•œ μ΄ˆκΈ°ν™”λœλ‹€.
그리고, μƒˆλ‘œμš΄ ν•¨μˆ˜ 객체가 μƒμ„±λ˜μ–΄ λ‹€μ‹œ doubleμ΄λΌλŠ” λ³€μˆ˜μ— ν• λ‹Ήλ˜λŠ” 것이닀.
즉, λ Œλ”λ§λ  λ•Œλ§ˆλ‹€ 맀번 μƒˆλ‘œμš΄ ν•¨μˆ˜ 객체가 ν• λ‹Ήλœλ‹€.

const double = (num) => {
  return num * 2;
};

μ΄λ•Œ, useCallback()을 μ‚¬μš©ν•΄μ„œ ν•¨μˆ˜ 객체λ₯Ό λ©”λͺ¨μ΄μ œμ΄μ…˜ν•΄μ£Όλ©΄, μ»΄ν¬λ„ŒνŠΈκ°€ λ¦¬λ Œλ”λ§λ˜μ–΄λ„ λ³€μˆ˜ double이 μ΄ˆκΈ°ν™”λ˜λŠ” 것을 막고, λ©”λͺ¨μ΄μ œμ΄μ…˜λœ ν•¨μˆ˜λ₯Ό λ‹€μ‹œ μ‚¬μš©ν•  수 있게 ν•œλ‹€.

const double = useCallback((num) => {
  return num * 2;
}, [value]);

2. 쒅속성 λ°°μ—΄(dependency array)

μ΄λ ‡κ²Œ λ©”λͺ¨μ΄μ œμ΄μ…˜ 된 ν•¨μˆ˜λŠ” 쒅속성 λ°°μ—΄ μ•ˆμ— μžˆλŠ” μš”μ†Œμ˜ 값이 λ³€κ²½λ˜μ§€ μ•ŠλŠ” 이상 λ‹€μ‹œ μ΄ˆκΈ°ν™”λ˜μ§€ μ•Šκ³ , λ³€κ²½λ˜μ—ˆμ„ λ•Œλ§Œ μƒˆλ‘­κ²Œ ν• λ‹Ήλœλ‹€.


useCallback이 μ–Έμ œ ν•„μš”ν• κΉŒ?

μžμ‹ μ»΄ν¬λ„ŒνŠΈμ— props둜 ν•¨μˆ˜λ₯Ό 전달해쀄 λ•Œ useCallback()을 μ‚¬μš©ν•˜λ©΄, λΆ€λͺ¨ μ»΄ν¬λ„ŒνŠΈκ°€ λ¦¬λ Œλ”λ§λ  λ•Œλ§ˆλ‹€ 같은 값을 λ¦¬ν„΄ν•˜λŠ” ν•¨μˆ˜λ₯Ό λΆˆν•„μš”ν•˜κ²Œ ν˜ΈμΆœν•˜λŠ” 것을 막을 수 μžˆλ‹€.

예제)

  1. μ•„λž˜ μ½”λ“œμ—μ„œ μˆ˜λŸ‰μ„ λ³€κ²½ν•˜λ©΄, quantity μƒνƒœκ°€ μ—…λ°μ΄νŠΈ 되며 μ»΄ν¬λ„ŒνŠΈ λ¦¬λ Œλ”λ§μ΄ μΌμ–΄λ‚œλ‹€.
  2. μ»΄ν¬λ„ŒνŠΈκ°€ λ¦¬λ Œλ”λ§λ˜λ©°, μ»΄ν¬λ„ŒνŠΈ λ‚΄λΆ€μ˜ getItems() ν•¨μˆ˜κ°€ μƒˆλ‘­κ²Œ λ§Œλ“€μ–΄μ§„λ‹€.
  3. ItemList μ»΄ν¬λ„ŒνŠΈ μ•ˆμ˜ useEffectλŠ” 쒅속성 λ°°μ—΄ μ•ˆμ— getItemsλ₯Ό 가지고 μžˆμœΌλ―€λ‘œ, getItems() ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€.

λ¬Έμ œλŠ” μ•„λž˜ μž₯λ°”κ΅¬λ‹ˆμ™€ 상관 μ—†λŠ” λ²„νŠΌμ„ λˆŒλ €μ„ λ•Œλ„ μ»΄ν¬λ„ŒνŠΈ 전체 λ¦¬λ Œλ”λ§μ΄ μΌμ–΄λ‚˜λ©° λΆˆν•„μš”ν•˜κ²Œ getItems() ν•¨μˆ˜κ°€ μ‹€ν–‰λœλ‹€λŠ” 점이닀.

⬇️
getItems() ν•¨μˆ˜μ— useCallback()λ₯Ό μ‚¬μš©ν•΄λ³΄λ©΄...
μ•„λž˜ μž₯λ°”κ΅¬λ‹ˆμ™€ 상관 μ—†λŠ” λ²„νŠΌμ„ λˆŒλŸ¬μ„œ μ»΄ν¬λ„ŒνŠΈ 전체 λ¦¬λ Œλ”λ§μ΄ μΌμ–΄λ‚˜λ”λΌλ„, getItems() ν•¨μˆ˜λŠ” quantity 값이 μ—…λ°μ΄νŠΈ λ˜μ§€ μ•ŠλŠ” ν•œ μ‹€ν–‰λ˜μ§€ μ•ŠλŠ”λ‹€. πŸ‘

이 글은 μ•„λž˜ 링크λ₯Ό μ°Έκ³ ν•˜μ—¬ μž‘μ„±ν•œ κΈ€μž…λ‹ˆλ‹€.
https://youtu.be/e-CnI8Q5RY4
https://youtu.be/XfUF9qLa3mU

profile
개발 곡뢀 기둝 λΈ”λ‘œκ·Έ

0개의 λŒ“κΈ€