HJS

useMemo

useMemo란?

useMemoReact Hook중 하나로, 연산 비용이 큰 계산의 불필요한 재연산을 방지하고 성능을 최적화하는데 사용됩니다.
useMemo는 특정 값이 변경되지 않는 한 기존의 계산된 값을 재사용하여, 불필요한 연산을 줄이고 렌더링 성능을 개선합니다.




2️⃣ useMemo vs 기존 게산 방식

🔹 일반적인 React의 계산 처리

React에서는 컴포넌트가 리렌더링될 때마다 모든 계산이 다시 수행됩니다. 이는 연산량이 많거나 데이터가 많을 경우 불필요한 성능 저하를 초래할 수 있습니다.

🧐 예시: 기존 방식에서의 연산 처리

import { useState } from "react";

function MyComponent({ numbers }) {
  const [count, setCount] = useState(0);

  // 배열의 합계를 계산
  const total = numbers.reduce((sum, num) => sum + num, 0);

  return (
    <div>
      <h1>합계: {total}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

불필요한 연산 발생: numbers가 변경되지 않더라도, total을 계산하는 연산이 컴포넌트가 리렌더링될 때마다 실행됩니다.


🔹 useMemo로 개선된 점

useMemo를 사용하면 연산 결과를 메모이제이션하여, 컴포넌트가 리렌더링되더라도 특정 값이 변경되지 않는 한 재연산을 방지할 수 있습니다.

import { useState, useMemo } from "react";

function MyComponent({ numbers }) {
  const [count, setCount] = useState(0);

  // useMemo를 사용하여 불필요한 연산 방지
  const total = useMemo(() => {
    console.log("총합 계산 중...");
    return numbers.reduce((sum, num) => sum + num, 0);
  }, [numbers]);

  return (
    <div>
      <h1>합계: {total}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

✔️ 불필요한 재연산 방지: numbers 배열이 변경되지 않는 한 total다시 계산하지 않고 기존 값을 유지합니다.
✔️ 렌더링 최적화: 상태 변경(count)으로 인한 리렌더링 시에도 total 계산이 불필요하게 실행되지 않습니다.




3️⃣ useMemo 사용 방법

🔹 기존 사용법

useMemo함수의존성 배열을 인자로 받으며, 의존성 배열에 포함된 값이 변경될 때마다 새로운 값을 계산합니다.

const memoizedValue = useMemo(() => {
  // 계산식
  return computedValue;
}, [dependencies]);

📌 파라미터

📌 반환 값

🔹 연산 메모이제이션관 useMemo 이해하기

🧐 예시1: 연산량이 많은 작업 최소화

function ExpensiveComponent({ numbers }) {
  const total = useMemo(() => {
    console.log("총합 계산 중...");
    return numbers.reduce((sum, num) => sum + num, 0);
  }, [numbers]);

  return <h1>합계: {total}</h1>;
}

✔️ useMemo를 사용하여 numbers가 변경되지 않는 한 총합 계산을 다시 수행하지 않습니다.
✔️ 연산량이 많은 경우 불필요한 CPU 사용을 줄이고 렌더링 성능 개선됩니다.

💡 그럼 그냥 의존성 배열을 비우면 되는 거 아닌가?
[]를 넣으면 최초 렌더링 시에만 연산이 수행되지만, 특정 값이 변경될 때 새로운 연산이 필요하면 문제가 발생할 수 있음.

🧐 예시2; 동적인 필터링 연산 최적화

function FilteredList({ items, query }) {
  const filteredItems = useMemo(() => {
    console.log("필터링 실행 중...");
    return items.filter(item => item.includes(query));
  }, [items, query]);

  return (
    <ul>
      {filteredItems.map((item, index) => (
        <li key={index}>{item}</li>
      ))}
    </ul>
  );
}

✔️ queryitems가 변경될 때만 필터링 로직이 실행됩니다.
✔️ 그렇지 않으면 이전 필터링된 결과를 그대로 재사용하여 성능 최적화합니다.