leebaek

[React] 리렌더링 최적화 3편 : useMemo Hook 본문

웹/React

[React] 리렌더링 최적화 3편 : useMemo Hook

leebaek 2025. 4. 11. 17:50

 

■ React 최적화 - 리렌더링 최적화를 위해서 ! 

■ useMemo

■ 예시 코드

■ 함수 안에서 반환 형태 차이: ( ) => ({ }) vs ( ) => { }

■ 주의할 점


■ React 최적화 - 리렌더링 최적화를 위해서 ! 

안녕하세요! 😊
오늘은 React 최적화 시리즈로 useMemo Hook 에 대해 알아보려고 합니다.

 

React 앱을 개발하다 보면 종종 "불필요한 렌더링" 때문에 성능이 저하되는 경우가 있습니다.
특히 렌더링마다 실행되는 비용이 많이 드는 연산 이 있을 때 문제가 되죠.


지난 포스팅에서는 React.memo 와 useCallback 으로 컴포넌트 리렌더링과 함수를 메모이제이션하는 방법을 알아봤는데요. 이번에는 연산 결과를 메모이제이션 하는 useMemo 를 다루겠습니다!

 

컴포넌트 메모제이션, 또는 컴포넌트의 props가 함수일 경우 최적화 방법에 대해 알고 싶으시다면,

이전 포스팅들을 참고해주시면 감사하겠습니다 !!

 

https://leebaek.tistory.com/152

 

[React] 리렌더링 최적화 2편 : useCallback Hook

■ React 최적화 - 리렌더링 최적화를 위해서 ! ■ useCallBack■ 예시 코드■ 1~2편 리렌더링 최적화 방법 복습 ■ React 최적화 - 리렌더링 최적화를 위해서 !  props가 원시값일 경우 최적화 방법

leebaek.tistory.com


■ useMemo

: 복잡한 계산 결과를 메모이제이션하여, 의존성이 변경될 때만 다시 계산하는 Hook

 

- 매 랜더링마다 동일한 계산을 반복하는 것은 비효율적임

useMemo를 사용하면 의존성 배열이 바뀌지 않는 이상 계산을 다시 하지 않고, 이전 결과를 재사용

 함수가 props로 전달될 때 불필요한 리렌더링 방지

 

첫번째 인자메모이제이션 하고 싶은 값

두번째 인자의존성 배열 ( *의존성 배열에 있는 값이 변경될 때만 재계산함 )

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

■ 예시 코드

□ useMemo 사용 X

- number가 변경될 때마다 매번 콘솔에 "계산 중..."이 출력됨

function App({ number }) {
  const expensiveCalculation = (num) => {
    console.log("계산 중...");
    return num * 1000;
  };

  const result = expensiveCalculation(number);

  return <div>결과: {result}</div>;
}

□ useMemo 사용 

- number가 바뀔 때만 계산되고, 그렇지 않으면 메모된 값을 사용함

function App({ number }) {
  const expensiveCalculation = (num) => {
    console.log("계산 중...");
    return num * 1000;
  };

  const result = useMemo(() => expensiveCalculation(number), [number]);

  return <div>결과: {result}</div>;
}

 

❓ useCallback과 같은거 아닌가요 ?? 

useMemo는 useCallback처럼 "함수 자체"를 메모이제이션 하는 Hook은 아닙니다.

"함수 실행 결과값(리턴값)"을 메모이제이션 합니다.


useMemo 사용  - 객체, 배열 메모제이션

- 의존성이 변하지 않는 이상 참조가 유지됨

// 배열
const items = useMemo(() => [1, 2, 3].filter(item => item > filter), [filter]);

// 객체
const config = useMemo(() => ({ text: `값은 ${value} 입니다` }), [value]);

■ 함수 안에서 반환 형태 차이: ( ) => ({ }) vs ( ) => { }

useMemo안에서 함수를 작성할 때 반환 형태 차이를 이해하면 좋습니다 ! 

 

1.암시적 반환 : ( ) => ( { } ) 과 ( ) => [ ]

const memoizedObject = useMemo(() => ({ a: 1, b: 2 }), []);

const memoizedArray = useMemo(() => [value * 2, value * 3], [value]);

 

- ( ) => ( { } ) : 객체 반환

- ( ) => [ ] : 배열 반환

- return 생략 가능

- useMemo안에서 객체나 배열 반환할 때 자주 사용함


2.명시적 반환 : ( ) => { return }

const memoizedObject = useMemo(() => {
  return { a: 1, b: 2 };
}, []);

const memoizedArray = useMemo(() => {
    return [value * 2, value * 3];
  }, [value]);

 

- 중괄호는 코드 블럭으로 인식되기 때문에 반드시 return이 필요함


주의할 점 !! 

- 가벼운 연산에는 오히려 비용이 더 커질 수 있으니, 복잡하고 무거운 계산에만 사용해야 합니다.

- 의존성 배열을 제대로 관리하지 않으면, 최신값이 반영되지 않을 수 있습니다.

- 메모리 사용량이 늘어날 수 있으므로 메모이제이션이 꼭 필요할 때만 사용해야 합니다.


언제 사용하는게 좋을까 ? 🧐

- 렌더링 마다 반복되는 복잡한 계산이 있을 때

- 렌더링 최적화를 위해 React.memo와 함께 사용할 때

- 사용자 입력이나 상태 변화에 따라 결과값이 자주 바뀌지 않을 때

- 객체나 배열을 자식 컴포넌트에 props로 전달할 때

 

사용하면 좋습니다.