All'alba vincerò

At dawn, I will win!

React

[React] useMemo(): 종속성 배열 값이 변경되지 않으면 재계산❌

나디아 Nadia 2024. 8. 21. 21:28

📌 useMemo()

: 계산된 값을 메모이제이션하여, 종속성 배열 값이 변경되지 않는 한 불필요한 재계산을 방지하는 훅

  • 값의 메모이제이션(값의 캐싱)을 통해 성능 최적화를 위해 사용
  • 종속성 배열에 명시된 값이 변경되지 않는 한, 이전에 계산된 값을 재사용한다.
    (React는 기본적으로 컴포넌트가 리렌더링될 때마다 모든 변수를 재계산한다.)
    ➡︎ 불필요한 재계산 방지
    ➡︎ 계산이 비싼 작업일 때, 성능 향상
  • 주로 계산량이 많거나, 리렌더링 시 재계산할 필요가 없는 값을 메모이제이션(memoization)하는 데 사용
  • 메모이제이션 된 컴포넌트가 불필요한 렌더링을 반복한다면, useMemo()를 사용하여 불필요한 렌더링을 줄일 수 있다.
    (메모이제이션 된 컴포넌트를 렌더링 제어하는 핵심 ➡︎ 컴포넌트 속성(props))

 

const cachedValue = useMemo(() => {
   // calculateValue 로직
}, [dependencies])
  • 매개변수
    • 콜백 함수(calculateValue)
      : 메모이제이션할 값 계산 함수
      • useMemo가 메모이제이션할 값을 반환
      • 함수는 계산이 비싼 작업을 포함할 수 있다.
      • 종속성 배열의 값이 변경될 때만 실행된다.
    • 종속성 배열 [dependencies]
      : 배열 안에 나열된 값들이 변경될 때만 매개변수로 전달된 콜백 함수가 다시 실행되도록 한다.
      • 이 배열에 있는 값들은 함수의 반환 값을 결정하는 데 영향을 미치는 값들이다.

 

 

 

⏩ useMemo() 특징

  • 불필요한 계산 방지
    • useMemo는 종속성 배열에 있는 값들이 변경되지 않는 한, 동일한 결과를 캐싱하여 재사용한다.
      ➡︎ 계산 비용이 큰 작업의 불필요한 재실행을 방지한다.
      (계산 비용이 큰 작업: 배열을 정렬하거나 필터링하는 작업, 복잡한 수학 연산 등을 수행할 때 등)
  • 컴포넌트 리렌더링 성능 최적화
    • 컴포넌트가 리렌더링될 때, useMemo를 사용하여 계산된 값을 재사용하면 리렌더링 성능을 최적화할 수 있다.
    • 자식 컴포넌트에 전달되는 값이 항상 같은 참조를 유지하도록 보장하여 불필요한 리렌더링을 줄일 수 있다.
  • 참조형 데이터 메모이제이션
    • 참조형 데이터(객체, 배열 등)는 기본적으로 참조가 동일하지 않으면 새로운 값을 생성한다.
      ➡︎ useMemo는 이러한 참조형 데이터의 메모이제이션에도 유용하다.

 

  • 불필요한 사용 주의
    • 간단한 계산이나 상태(state)가 자주 변경되지 않는 경우에는 사용하지 않는 것이 좋다.

 

 

 

예제) 카운트 컴포넌트

  • 카운트 증가 버튼 클릭
    : count 값이 변경되며, squaredValue가 재계산된다.

    • 콘솔에 "Calculating squared value..."가 출력
  • 메시지 토글 버튼 클릭
    : showMessage 값이 변경되어 메시지가 나타나거나 사라진다.

    • count와 관련된 계산은 영향을 받지 않으며, squaredValue는 메모이제이션된 값을 그대로 유지
import React, { useMemo, useState } from 'react';

function ExampleComponent() {
  const [count, setCount] = useState(0);
  const [showMessage, setShowMessage] = useState(true);

  // useMemo를 사용하여 메모이제이션된 값 계산
  const squaredValue = useMemo(() => {
    console.log('Calculating squared value...');
    
    return count * count;
  }, [count]); // count가 변경될 때만 재계산


  return (
    <div>
      <p>Count: {count}</p>
      <p>Squared Value: {squaredValue}</p>
      <button onClick={() => setCount(count + 1)}>Increment Count</button>
      <button onClick={() => setShowMessage(!showMessage)}>Toggle Message</button>
      {showMessage && <p>Message is visible!</p>}
    </div>
  );
}

export default ExampleComponent;

 

 


useMemo()  vs  useCallback() 

  • useMemo()와 useCallback() 모두 자식 컴포넌트를 최적화할 때 사용
  useMemo() useCallback()
목적 값을 메모이제이션하여
계산 성능 최적화
함수를 메모이제이션하여
불필요한 함수 재생성 방지
사용 대상 계산된 값 (결과) 함수 (콜백)
사용 계산이 비싼 작업의 결과를 캐싱하고
재사용할 때
자식 컴포넌트에 콜백 함수를 전달할 때,
참조를 일정하게 유지할 때
메모이제이션
대상
반환 값 (계산 결과) 함수 자체
종속성 배열 종속성 배열의 값이 변경될 때만 재계산 종속성 배열의 값이 변경될 때만 새 함수 생성

 

 

  • useCallback() 훅 함수는 내부적으로 useMemo() 훅을 사용한다. 
function useCallback(fn, dependencies) {
  return useMemo(() => fn, dependencies);
}

 


✅ memo()  vs  useMemo()

  • memo()와 useMemo() 모두 성능 최적화에 사용
  memo() useMemo()
목적 컴포넌트의 불필요한 리렌더링을 방지 계산된 값의 불필요한 재계산을 방지
사용 시기 리렌더링이 자주 발생하지만,
props가 변경되지 않는 컴포넌트의 경우
복잡한 계산이나,
값이 변할 때만 재계산이 필요한 경우
적용 대상 컴포넌트 자체를 메모이제이션 값의 계산을 메모이제이션
사용 방식 고차 컴포넌트로, 컴포넌트를 감싸서 사용 훅으로, 컴포넌트 내부에서 사용
매개변수 1. 컴포넌트(자식 컴포넌트)
2. 비교 함수(선택)
1. 값 계산 함수
2. 종속성 배열
컴포넌트
렌더링
props가 변경되지 않으면
컴포넌트 리렌더링 방지
종속성 배열의 값이 변경되지 않으면
값 계산 방지

 

 


 

 

useMemo – React

The library for web and native user interfaces

ko.react.dev

 

 

useCallback – React

The library for web and native user interfaces

ko.react.dev