useMemo()

1. κ°œμš”

useMemo()λŠ” μ»΄ν¬λ„ŒνŠΈμ˜ μ΅œμ ν™”λ₯Ό μ‹œν‚€κΈ° μœ„ν•΄ μ‚¬μš©λ˜λŠ” hook 쀑 ν•˜λ‚˜μ΄λ‹€. useMemo()μ—μ„œ MemoλŠ” Memoization을 λœ»ν•˜λŠ”λ° μ΄λŠ” 기쑴에 μˆ˜ν–‰ν•œ μ—°μ‚°μ˜ 결과값을 μ–΄λ”˜κ°€μ— μ €μž₯ν•΄ 두고 λ™μΌν•œ μž…λ ₯이 λ“€μ–΄μ˜€λ©΄ μž¬ν™œμš©ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ° 기법을 λ§ν•œλ‹€.


2. useMemo()λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” μ»΄ν¬λ„ŒνŠΈμ˜ λžœλ”λ§

ν•¨μˆ˜ν˜• μ»΄ν¬λ„ŒνŠΈλ„ 말 κ·ΈλŒ€λ‘œ ν•˜λ‚˜μ˜ ν•¨μˆ˜μ΄λ‹€. 즉, λžœλ”λ§μ΄ λœλ‹€λŠ” 것은 ν•¨μˆ˜κ°€ 호좜이 되고 ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λŠ” μ΄ˆκΈ°ν™”κ°€ λœλ‹€.

μ•„λž˜μ™€ 같은 μ»΄ν¬λ„ŒνŠΈκ°€ μžˆλ‹€κ³  κ°€μ •ν•˜μž.

import React from "react";

const Test = () => {
  const calculate = () => {
    // μ—„μ²­λ‚˜κ²Œ λ³΅μž‘ν•œ 둜직
    console.log("λ‚˜ μ§€κΈˆ ν•¨μˆ˜ μ‹€ν–‰ν•˜κ³  μžˆμ–΄!");
    return 10;
  };

  const result = calculate();

  return <div>{result}</div>;
};

export default Test;

μœ„μ˜ μ½”λ“œλ₯Ό 보면 App μ»΄ν¬λ„ŒνŠΈκ°€ λžœλ”λ§μ΄ 된면 result에 calculate()ν•¨μˆ˜κ°€ μ‹€ν–‰λ˜μ–΄ 리턴값이 ν• λ‹Ήλœλ‹€.

μ»΄ν¬λ„ŒνŠΈλ₯Ό λ¦¬λžœλ”λ§μ‹œμΌœλ³΄μž. μ»΄ν¬λ„ŒνŠΈκ°€ λ¦¬λžœλ”λ§μ€ state, props의 λ³€ν™”κ°€ μžˆμ„ λ•Œ ν•œλ‹€. μ—¬κΈ°μ„œλŠ” κ°„λ‹¨νžˆ stateλ₯Ό λ³€ν™”μ‹œμΌœ λ¦¬λžœλ”λ§μ„ ν•΄λ³΄μž.

μ•„λž˜μ™€ 같이 μ½”λ“œλ₯Ό μΆ”κ°€ μž‘μ„±ν•œλ‹€.

import React, { useState } from "react";

const Test = () => {
  const [render, setRender] = useState(false);

  const calculate = () => {
    // μ—„μ²­λ‚˜κ²Œ λ³΅μž‘ν•œ 둜직
    console.log("λ‚˜ μ§€κΈˆ ν•¨μˆ˜ μ‹€ν–‰ν•˜κ³  μžˆμ–΄!");
    return 10;
  };

  const result = calculate();

  const onClickBtn = () => setRender((prev) => !prev);

  return (
    <div>
      {result}
      <button onClick={onClickBtn}>λ¦¬λžœλ”λ§</button>
    </div>
  );
};

export default Test;

이제 λ¦¬λžœλ”λ§ λ²„νŠΌμ„ λˆ„λ₯Ό λ•Œ λ§ˆλ‹€ state값이 λ³€ν•˜κ²Œ λ˜μ–΄ μ»΄ν¬λ„ŒνŠΈκ°€ λ¦¬λžœλ”λ§ λœλ‹€. μ•„λž˜μ˜ μ½˜μ†”μ„ 보자.

useMemo_rerender1

μ»΄ν¬λ„ŒνŠΈκ°€ λ¦¬λžœλ”λ§ 될 λ•Œλ§ˆλ‹€ calculate()ν•¨μˆ˜κ°€ λ‹€μ‹œ ν˜ΈμΆœλ˜λŠ” 것을 λ³Ό 수 μžˆλ‹€. λˆˆμ— λ³΄μ΄λŠ” result값은 κ°™μ§€λ§Œ λ¦¬λžœλ”λ§ 될 λ•Œλ§ˆλ‹€ λ³€μˆ˜κ°€ μ΄ˆκΈ°ν™” 되기 λ•Œλ¬Έμ— calculate()ν•¨μˆ˜κ°€ 반볡적으둜 호좜이 λœλ‹€. λ§Œμ•½ calculate()ν•¨μˆ˜κ°€ 무거운 일을 ν•˜κ²Œ λœλ‹€λ©΄ λΉ„νš¨μœ¨μ μΈ 과정을 κ³„μ†ν•΄μ„œ 거치게 λ˜λŠ” 것이닀. 이λ₯Ό ν•΄κ²°ν•  수 μžˆλŠ” 것이 λ°”λ‘œ useMemo()이닀.


3. useMemo()λ₯Ό μ‚¬μš©ν•œ μ»΄ν¬λ„ŒνŠΈμ˜ λžœλ”λ§

μ΄λ²ˆμ—λŠ” useMemo()λ₯Ό μ‚¬μš©ν•˜μ—¬ μ»΄ν¬λ„ŒνŠΈλ₯Ό λžœλ”λ§ ν•΄λ³΄μž.

λ¨Όμ € useMemo()의 κΈ°λ³Έ μ‚¬μš©λ²•μ€ μ•„λž˜μ™€ κ°™λ‹€. μ‚¬μš©λ²• const value = useMemo(function, deps)

  • function: Memoization을 ν•  값을 κ³„μ‚°ν•΄μ„œ 리턴해 쀄 μ½œλ°±ν•¨μˆ˜

  • deps: μ˜μ‘΄μ„± λ°°μ—΄λ‘œ useEffect()의 deps와 κ°™λ‹€.

2. useMemo()λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” μ»΄ν¬λ„ŒνŠΈμ˜ λžœλ”λ§μ—μ„œ μž‘μ„±ν•œ μ½”λ“œ 쀑 const result = calculate();λ₯Ό μ•„λž˜μ™€ 같이 μˆ˜μ •ν•˜μž.

const result = useMemo(() => {
  return calculate();
}, []);

calculate()ν•¨μˆ˜μ˜ return값을 Memoization을 ν•˜μ—¬ result에 ν• λ‹Ήν•˜κ³  μžˆλ‹€. 그리고 μ˜μ‘΄μ„± 배열은 λΉ„μ–΄μžˆκΈ° λ•Œλ¬Έμ— μ»΄ν¬λ„ŒνŠΈκ°€ 처음 생성될 λ•Œλ§Œ useMemo()의 μ½œλ°±ν•¨μˆ˜κ°€ μ‹€ν–‰λœλ‹€.

μœ„μ™€ 같이 μˆ˜μ • ν•œ ν›„ 아무리 λ¦¬λžœλ”λ§ λ²„νŠΌμ„ λˆŒλŸ¬λ„ calculate()ν•¨μˆ˜κ°€ ν˜ΈμΆœλ˜μ§€ μ•ŠλŠ”λ‹€.

λ§Œμ•½ μ˜μ‘΄μ„± 배열에 μ–΄λ– ν•œ 값이 μžˆλ‹€λ©΄ κ·Έ 값이 λ³€ν•  λ•Œ λ§ˆλ‹€ μ½œλ°±ν•¨μˆ˜λ₯Ό λ‹€μ‹œ ν˜ΈμΆœν•œλ‹€. ν•΄λ‹Ή 경우λ₯Ό μ½”λ“œμ™€ ν•¨κ»˜ μ‚΄νŽ΄λ³΄μž. μ•„λž˜μ™€ 같이 μ½”λ“œλ₯Ό μΆ”κ°€ 및 μˆ˜μ •ν•œλ‹€.

import React, { useState, useMemo, useEffect } from "react";

const Test = () => {
  const [render, setRender] = useState(false);
  const [num, setNum] = useState(1);

  const calculate = () => {
    // μ—„μ²­λ‚˜κ²Œ λ³΅μž‘ν•œ 둜직
    console.log("λ‚˜ μ§€κΈˆ ν•¨μˆ˜ μ‹€ν–‰ν•˜κ³  μžˆμ–΄!");
    return num * 20;
  };

  const result = useMemo(() => {
    return calculate();
  }, [num]);

  const onClickPlusBtn = () => setNum((prev) => prev + 1);

  const onClickBtn = () => setRender((prev) => !prev);

  useEffect(() => {
    console.log("μ»΄ν¬λ„ŒνŠΈκ°€ λžœλ”λ§ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.");
  }, [render, num]);

  return (
    <div>
      {result}
      <button onClick={onClickPlusBtn}>Plus</button>
      <button onClick={onClickBtn}>λ¦¬λžœλ”λ§</button>
    </div>
  );
};

export default Test;

μ΄λ²ˆμ—λŠ” useMemo()의 μ˜μ‘΄μ„± 배열에 num값을 μΆ”κ°€ ν•˜μ˜€κ³  num값은 state으둜 Plus λ²„νŠΌμ„ λˆ„λ₯΄ λ•Œ λ§ˆλ‹€ μ¦κ°€ν•œλ‹€. 즉, useMemo()의 μ½œλ°±ν•¨μˆ˜λŠ” Plus λ²„νŠΌμ„ 눌러 num값이 μ¦κ°€ν•˜κ²Œ 되면 λ‹€μ‹œ 호좜이 λ˜μ–΄ μƒˆλ‘œμš΄ result값을 κ°€μ§€κ²Œ λœλ‹€. ν•˜μ§€λ§Œ μ—¬μ „νžˆ λ¦¬λžœλ”λ§ λ²„νŠΌμ„ λˆ„λ₯Ό λ•Œμ—λŠ” μ½œλ°±ν•¨μˆ˜κ°€ λ‹€μ‹œ 호좜 λ˜μ§€ μ•ŠλŠ”λ‹€.

μ•„λž˜λŠ” 각각의 λ²„νŠΌμ„ λˆŒλ €μ„ λ•Œ λ‚˜νƒ€λ‚˜λŠ” μ½˜μ†”μ˜ λͺ¨μŠ΅μ΄λ‹€.

useMemo_rerender2

4. useMemo()λ₯Ό 항상 μ‚¬μš©ν•˜μ—¬ λžœλ”λ§ μ΅œμ ν•˜λ©΄ 쒋은걸끼?

정닡은 κ·Έλ ‡μ§€ μ•Šλ‹€. 값을 μž¬ν™œμš©ν•˜κΈ° μœ„ν•΄ λ”°λ‘œ λ©”λͺ¨λ¦¬λ₯Ό μ†ŒλΉ„ν•˜μ—¬ μ €μž₯을 ν•˜κΈ° λ•Œλ¬Έμ— λΆˆν•„μš”ν•œ κ°’κΉŒμ§€ λͺ¨λ‘ useMemo()λ₯Ό μ‚¬μš©ν•˜μ—¬ Memoization을 ν•˜κ²Œ λœλ‹€λ©΄ 였히렀 μ„±λŠ₯은 더 μ•ˆ μ’‹μ•„μ§ˆ 수 μžˆλ‹€. κ·Έλ ‡κΈ° λ•Œλ¬Έμ— κΌ­ ν•„μš”ν•  λ•Œμ—λ§Œ μ μ ˆν•˜κ²Œ useMemo()λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.


5. Conclusion

λ¦¬μ•‘νŠΈλ‘œ μ—¬λŸ¬ ν”„λ‘œμ νŠΈλ₯Ό μ§„ν–‰ν–ˆμ§€λ§Œ useMemo()λ₯Ό μ‚¬μš©ν•œ 적은 ν•œ λ²ˆλ„ μ—†μ—ˆλ‹€. κ·Έ μ΄μœ λŠ” 첫 번째 useMemo()에 λŒ€ν•΄ λͺ°λžκ³ , 두 번째 λžœλ”λ§ μ΅œμ ν™”μ— λŒ€ν•œ 고민을 ν•΄ λ³Έ 적이 μ—†κΈ° λ•Œλ¬Έμ΄λ‹€. κ·Έλž˜μ„œ μ§€κΈˆκΉŒμ§€ μ§„ν–‰ν–ˆλ˜ 그리고 μ§„ν–‰ν•˜κ³  μžˆλŠ” λ¦¬μ•‘νŠΈ ν”„λ‘œμž­νŠΈλ₯Ό λ¦¬νŒ©ν† λ§ ν•  λ•Œ λžœλ”λ§ μ΅œμ ν™”κ°€ ν•„μš”ν•˜λ‹€λ©΄ 적극적으둜 useMemo()λ₯Ό μ‚¬μš©ν•  κ³„νšμ΄λ‹€. κ·Έλ ‡λ‹€κ³  λ¬΄λΆ„λ³„ν•˜κ²Œ μ‚¬μš©μ€ ν•˜μ§€ μ•Šμ„κ±°λ‹€.πŸ˜ƒ


μ°Έκ³ 

17. useMemo λ₯Ό μ‚¬μš©ν•˜μ—¬ μ—°μ‚°ν•œ κ°’ μž¬μ‚¬μš©ν•˜κΈ° [React] useMemo μ‚¬μš©λ²• 및 예제

도움이 많이 λ˜μ—ˆλ˜ 유튜브 🎬

  • React Hooks에 μ·¨ν•œλ‹€ - useMemo μ œλŒ€λ‘œ μ‚¬μš©ν•˜κΈ° | λ¦¬μ•‘νŠΈ ν›…μŠ€ μ‹œλ¦¬μ¦ˆ React Hooks에 μ·¨ν•œλ‹€ - useMemo μ œλŒ€λ‘œ μ‚¬μš©ν•˜κΈ° | λ¦¬μ•‘νŠΈ ν›…μŠ€ μ‹œλ¦¬μ¦ˆ


πŸ‘†

πŸ“… 2022-08-02

Last updated