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๊ฐ’์ด ๋ณ€ํ•˜๊ฒŒ ๋˜์–ด ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋žœ๋”๋ง ๋œ๋‹ค. ์•„๋ž˜์˜ ์ฝ˜์†”์„ ๋ณด์ž.

์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋žœ๋”๋ง ๋  ๋•Œ๋งˆ๋‹ค 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๊ฐ’์„ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค. ํ•˜์ง€๋งŒ ์—ฌ์ „ํžˆ ๋ฆฌ๋žœ๋”๋ง ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ๋•Œ์—๋Š” ์ฝœ๋ฐฑํ•จ์ˆ˜๊ฐ€ ๋‹ค์‹œ ํ˜ธ์ถœ ๋˜์ง€ ์•Š๋Š”๋‹ค.

์•„๋ž˜๋Š” ๊ฐ๊ฐ์˜ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ๋‚˜ํƒ€๋‚˜๋Š” ์ฝ˜์†”์˜ ๋ชจ์Šต์ด๋‹ค.


4. useMemo()๋ฅผ ํ•ญ์ƒ ์‚ฌ์šฉํ•˜์—ฌ ๋žœ๋”๋ง ์ตœ์ ํ•˜๋ฉด ์ข‹์€๊ฑธ๋ผ?

์ •๋‹ต์€ ๊ทธ๋ ‡์ง€ ์•Š๋‹ค. ๊ฐ’์„ ์žฌํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋”ฐ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์†Œ๋น„ํ•˜์—ฌ ์ €์žฅ์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆํ•„์š”ํ•œ ๊ฐ’๊นŒ์ง€ ๋ชจ๋‘ useMemo()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Memoization์„ ํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ์˜คํžˆ๋ ค ์„ฑ๋Šฅ์€ ๋” ์•ˆ ์ข‹์•„์งˆ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๊ผญ ํ•„์š”ํ•  ๋•Œ์—๋งŒ ์ ์ ˆํ•˜๊ฒŒ useMemo()๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.


5. Conclusion

๋ฆฌ์•กํŠธ๋กœ ์—ฌ๋Ÿฌ ํ”„๋กœ์ ํŠธ๋ฅผ ์ง„ํ–‰ํ–ˆ์ง€๋งŒ useMemo()๋ฅผ ์‚ฌ์šฉํ•œ ์ ์€ ํ•œ ๋ฒˆ๋„ ์—†์—ˆ๋‹ค. ๊ทธ ์ด์œ ๋Š” ์ฒซ ๋ฒˆ์งธ useMemo()์— ๋Œ€ํ•ด ๋ชฐ๋ž๊ณ , ๋‘ ๋ฒˆ์งธ ๋žœ๋”๋ง ์ตœ์ ํ™”์— ๋Œ€ํ•œ ๊ณ ๋ฏผ์„ ํ•ด ๋ณธ ์ ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ๊ทธ๋ž˜์„œ ์ง€๊ธˆ๊นŒ์ง€ ์ง„ํ–‰ํ–ˆ๋˜ ๊ทธ๋ฆฌ๊ณ  ์ง„ํ–‰ํ•˜๊ณ  ์žˆ๋Š” ๋ฆฌ์•กํŠธ ํ”„๋กœ์žญํŠธ๋ฅผ ๋ฆฌํŒฉํ† ๋ง ํ•  ๋•Œ ๋žœ๋”๋ง ์ตœ์ ํ™”๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด ์ ๊ทน์ ์œผ๋กœ useMemo()๋ฅผ ์‚ฌ์šฉํ•  ๊ณ„ํš์ด๋‹ค. ๊ทธ๋ ‡๋‹ค๊ณ  ๋ฌด๋ถ„๋ณ„ํ•˜๊ฒŒ ์‚ฌ์šฉ์€ ํ•˜์ง€ ์•Š์„๊ฑฐ๋‹ค.๐Ÿ˜ƒ


์ฐธ๊ณ 

17. useMemo ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฐ์‚ฐํ•œ ๊ฐ’ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ [React] useMemo ์‚ฌ์šฉ๋ฒ• ๋ฐ ์˜ˆ์ œ

๋„์›€์ด ๋งŽ์ด ๋˜์—ˆ๋˜ ์œ ํŠœ๋ธŒ ๐ŸŽฌ


๐Ÿ‘†

๐Ÿ“… 2022-08-02

Last updated