Library/React

[ React ] useMemo์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.

ma.caron_g 2024. 4. 4. 17:58

์ฐธ๊ณ  ์‚ฌ์ดํŠธ

๋ฆฌ์•กํŠธ ๊ณต์‹ ๋ฌธ์„œ - useMemo

 

 

 

๐Ÿ“ useMemo

useMemo๋Š” ์žฌ๋ Œ๋”๋ง ๊ฐ„ ๊ณ„์‚ฐ ๊ฒฐ๊ณผ๋ฅผ *์บ์‹œ(Cache)ํ•  ์ˆ˜ ์žˆ๋Š” React Hook์ด๋‹ค.

๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ์žฌ๊ณ„์‚ฐ์„ ๊ฑด๋„ˆ๋›ฐ๊ธฐ ์œ„ํ•˜์—ฌ ์‚ฌ์šฉํ•œ๋‹ค.

 

*์บ์‹œ(Cache): ์ปดํ“จํ„ฐ ๊ณผํ•™์—์„œ ๋ฐ์ดํ„ฐ๋‚˜ ๊ฐ’์„ ๋ฏธ๋ฆฌ ๋ณต์‚ฌํ•ด ๋†“๋Š” ์ž„์‹œ ์žฅ์†Œ๋กœ ๋ฐ์ดํ„ฐ ์ ‘๊ทผํ•˜๋Š” ์‹œ๊ฐ„์ด ์˜ค๋ž˜๊ฑธ๋ฆฌ๊ฑฐ๋‚˜ ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜๋Š” ์‹œ๊ฐ„์„ ์ ˆ์•ฝํ•˜๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์— ์‚ฌ์šฉ

์ถœ์ฒ˜: Wikipedia

 

๋ฐ˜ํ™˜๊ฐ’์„ ์บ์‹ฑํ•˜๋Š” ๊ฒƒ์„ ๋ฉ”๋ชจ์ด์ œ์ด์…˜(memoization)์ด๋ผ๊ณ ๋„ ํ•˜๋ฉฐ, ์ด๊ฒƒ์ด ์ด Hook์ด ๋ถˆ๋ฆฌ๋Š” ์ด์œ ์ด๋‹ค.

 

๐Ÿ“ข ์ฐธ์กฐ

useMemo ์žฌ๋ Œ๋”๋ง ๊ฐ„์˜ ๊ณ„์‚ฐ์„ ์บ์‹œํ•˜๋ ค๋ฉด ๊ตฌ์„ฑ ์š”์†Œ์˜ ์ตœ์ƒ์œ„ ์ˆ˜์ค€์—์„œ ํ˜ธ์ถœํ•œ๋‹ค.

const cachedValue = useMemo(calculateValue, [dependencies])

 

๐Ÿ“ฆ Parameters

calculateValue: ์บ์‹œํ•˜๋ ค๋Š” ๊ฐ’์„ ๊ณ„์‚ฐํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

์ˆœ์ˆ˜ํ•ด์•ผํ•˜๊ณ , ์ธ์ˆ˜๋ฅผ ์ทจํ•˜์ง€ ์•Š์•„์•ผํ•˜๋ฉฐ, ๋ชจ๋“  ์œ ํ˜•์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•ด์•ผํ•œ๋‹ค.

React๋Š” ์ดˆ๊ธฐ ๋ Œ๋”๋ง ์ค‘ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ , ๋‹ค์Œ ๋ Œ๋”๋ง์—์„œ dependencies๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋™์ผํ•œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

dependencies: calculateValue(ํ•จ์ˆ˜)์ฝ”๋“œ ๋‚ด๋ถ€์—์„œ ์ฐธ์กฐ๋˜๋Š” ๋ชจ๋“  ๋ฐ˜์‘ ๊ฐ’์˜ ๋ชฉ๋ก์ด๋‹ค.

๋ฐ˜์‘ํ˜• ๊ฐ’์—๋Š” props, state ๋ฐ ๊ตฌ์„ฑ ์š”์†Œ ๋ณธ์ฒด ๋‚ด๋ถ€์— ์ง์ ‘ ์„ ์–ธ๋œ ๋ชจ๋“  ๋ณ€์ˆ˜์™€ ํ•จ์ˆ˜๊ฐ€ ํฌํ•จ๋œ๋‹ค.

 

๐ŸŽ Return

์ดˆ๊ธฐ ๋ Œ๋”๋ง ์‹œ ์ธ์ˆ˜ ์—†์ด useMemo ํ˜ธ์ถœํ•œ cacluateValue(ํ•จ์ˆ˜)์˜ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

๋‹ค์Œ ๋ Œ๋”๋ง์—์„œ dependencies๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ ์ด๋ฏธ ์ €์žฅ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ , ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ calculateValue๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜์—ฌ ๋ฐ˜ํ™˜๋œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

โš ๏ธ ์ฃผ์˜์‚ฌํ•ญ

• useMemo๋Š” Hook์ด๋ฏ€๋กœ ์ปดํฌ๋„ŒํŠธ ์ตœ์ƒ์œ„ ์ˆ˜์ค€ ์ด๋‚˜ ์ž์ฒด Hook์—์„œ๋งŒ ํ˜ธ์ถœ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

• Strict(์—„๊ฒฉ) ๋ชจ๋“œ์—์„œ๋Š” useMemo๊ฐ€ ๋‘ ๋ฒˆ ํ˜ธ์ถœ๋˜์ง€๋งŒ, ํ”„๋กœ๋•์…˜์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค.

• React๋Š” ํŠน๋ณ„ํ•œ ์ด์œ ๊ฐ€ ์—†๋Š” ํ•œ ์บ์‹œ๋œ ๊ฐ’์„ ๋ฒ„๋ฆฌ์ง€ ์•Š๋Š”๋‹ค.

 

โœ’๏ธ ์‚ฌ์šฉ

• ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ์žฌ๊ณ„์‚ฐ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

• ๊ตฌ์„ฑ์š”์†Œ ๋ฆฌ-๋ Œ๋”๋ง ๊ฑด๋„ˆ๋›ฐ๊ธฐ

 

 

... PT ๋ฐ›๊ณ  ์™€์„œ  ์ž‘์„ฑํ•  ์˜ˆ์ •

๊ณต์‹ ๋ฌธ์„œ ์˜ˆ์‹œ๊ฐ€ ๊ธธ์–ด ๊ตฌ๋…์ž๋ถ„๊ป˜์„œ ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ๋„๋ก ์˜ˆ์‹œ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค์–ด๋ณด๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

 

To Be Develop...

 

import React, { useMemo, useRef, useState } from "react";
import "./App.css";

// ์—ฐ์‚ฐ์ด 3์ดˆ ๊ฑธ๋ฆฌ๋Š” ํ•จ์ˆ˜๊ฐ€ ์žˆ๋‹ค๊ณ  ํ•  ๋•Œ,
function delayFunc(
  preVal: number,
  target: React.MutableRefObject<HTMLInputElement>
) {
  const startTime = Date.now();
  setTimeout(() => {
    if (target) {
      console.log(Date.now() - startTime);
      target.current.value = (preVal + 1).toString();
    }
  }, 3000);
}

function basicFunc(preVal: number) {
  console.log("๋น ๋ฅธ ํ•จ์ˆ˜ ์žฌ๊ณ„์‚ฐ");
  return preVal + 1;
}

export function DelayMemo() {
  const delayInputRef = useRef<React.MutableRefObject<HTMLInputElement> | null>(
    null
  );
  const [value, setValue] = useState<number>(0);
  const [memo, setMemo] = useState<number>(0);

  const basic = basicFunc(value);

  const memoization = useMemo(() => {
    return delayFunc(memo, delayInputRef);
  }, [memo]);

  //   const memoization = delayFunc(memo, delayInputRef);

  return (
    <>
      <div>
        <div>
          value <input value={basic} readOnly />
        </div>{" "}
        <div>
          memoization <input ref={delayInputRef} value={memoization} readOnly />
        </div>
      </div>
      <br />
      <div>
        <button
          onClick={() => {
            setValue((prev) => {
              return prev + 1;
            });
          }}
          style={{ margin: "0 10px" }}
        >
          Value Up
        </button>
        <button
          onClick={() => {
            setMemo((prev) => {
              return prev + 1;
            });
          }}
          style={{ margin: "0 10px" }}
        >
          Dependence Up
        </button>
      </div>
    </>
  );
}

export default App;

 

์ฝ”๋“œ๋ฅผ ํ™•์ธํ•˜๋ฉด 30๋ฒˆ์งธ ์ค„์€ useMemo()๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ Œ๋”๋ง๋งˆ๋‹ค ๊ณ„์† ํ˜ธ์ถœ๋˜๋„๋ก ๋˜์–ด์žˆ๊ณ , 34๋ฒˆ ์งธ ์ค„์€ useMemo()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ memo๋ผ๋Š” ๊ฐ’์— ์˜์กดํ•˜์—ฌ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜๊ณ  ์žˆ๋‹ค.

 

์ฃผ์„์„ ํ•˜๋‚˜์”ฉ ํ’€์–ด๊ฐ€๋ฉด์„œ ์‹คํ–‰ํ•ด๋ณด์ž.

 

useMemo()๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์„ ๋•Œ์ด๋‹ค.

 

์˜์กด๊ฐ’(memo)๋ฅผ ์˜ฌ๋ฆฌ์ง€๋„ ์•Š์•˜๋Š”๋ฐ Console์ฐฝ์„ ํ™•์ธํ•ด๋ณด๋ฉด, 3์ดˆ๊ฐ€ ๊ฑธ๋ฆฌ๋Š” ๋ฌด๊ฑฐ์šด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ณ ์žˆ๋‹ค.

 

useMemo()๋ฅผ ํ™œ์„ฑํ™”ํ•˜์—ฌ ์‹คํ–‰ํ•ด๋ณด๋ฉด

 

์˜์กด์„ฑ ์—†๋Š” value๊ฐ’์„ up ์‹œํ‚ค๊ณ  ์‹œ๊ฐ„ ๊ณ„์‚ฐ์„ ์œ„ํ•ด startTime์„ ์ €์žฅํ–ˆ๋‹ค.

๊ทธ ์ดํ›„์— ์ฐํžŒ ์ฝ˜์†”์€ 3์ดˆ๊ฐ€ ์ง€๋‚ฌ์Œ์—๋„ ๋กœ๊ทธ๊ฐ€ ์ฐํžˆ์ง€ ์•Š์€ ๊ฒƒ์„ ๋ณด์—ฌ์ฃผ๊ธฐ ์œ„ํ•ด ์ฐ์—ˆ๋‹ค.

๋กœ๊ทธ๊ฐ€ ์ฐํžˆ์ง€์•Š์•˜๋‹ค๋Š” ๊ฒƒ์€ ์ฆ‰, value๊ฐ’์„ up ์‹œ์ผฐ์Œ์—๋„ delay์—ฐ์‚ฐ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

 

์˜์กด์„ฑ๊ฐ’์„ ์˜ฌ๋ฆฌ๋‹ˆ ๋‹น์—ฐํžˆ useMemo()๋กœ ํ˜ธ์ถœํ•˜์ง€ ์•Š๋Š” ๋น ๋ฅธ ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜์–ด ๋กœ๊ทธ๊ฐ€ ์ฐํžˆ๊ณ  3์ดˆ ๋’ค ๋”œ๋ ˆ์ด๊ฐ€ ์žˆ๋Š” ํ•จ์ˆ˜์˜ ๋กœ๊ทธ๊ฐ€ ์ฐํžŒ๋‹ค.

 

์ด๋กœ์จ ๋ Œ๋”๋ง๋งˆ๋‹ค ์—ฐ์‚ฐ์— ๋ฌด๋ฆฌ๊ฐ€ ์žˆ๋Š” ๊ฐ’์€ ์บ์‹œํ•˜์—ฌ ์„ฑ๋Šฅ์— ์•…ํ™”๋ฅผ ๋ณด๊ฐ•ํ•  ์ˆ˜ ์žˆ๋‹ค.