리액트 훅 | useMemo에 대해 알아보기

2025. 8. 13. 19:13·FRONTEND/React

 

리액트를 사용하다 보면, 상태가 변경될 때 불필요한 연산이 계속 실행되어 화면이 느려지는 경우가 있습니다.

이때 유용하게 쓸 수 있는 도구가 바로 useMemo입니다 !

 

1. useMemo란?

값을 메모이제이션(memoization)해서 필요할 때만 다시 계산하도록 도와줍니다.

쉽게 말해, "이 값은 변하지 않으면 다시 계산하지 말고, 이전 값을 그대로 가져다 써"라고 알려주는 도구입니다.

 

useMemo가 왜 필요한가?

함수형 컴포넌트는 상태가 변경되면 함수 전체가 다시 재렌더됩니다.

이 과정에서 컴포넌트 안에 있는 모든 변수와 함수들이 다시 불러와지는데요,

 

이때, 렌더링마다 무거운 연산이 계속 실행되어 성능이 저하되는 문제가 발생하거나

useEffect 의존성에 객체를 넣은 경우 값이 바뀌지 않아도 참조가 달라져 effect가 매번 실행되는 문제를 마주할 수 있습니다.

 

즉, 불필요한 재계산이 일어나는 것을 막기 위해 useMemo를 사용합니다 !

 

기본 문법

const fn = useMemo(() => {
  // 계산 로직
  return 값;
}, [의존성1, 의존성2]);

- 첫번째 인자 : 계산을 수행하는 함수

- 두번째 인자 : 의존성 배열 - 해당 값이 변경될 때만 계산을 다시 수행

(의존성이 변하지 않으면 이전 계산값을 재사용)

 

2. 예제로 보는 useMemo : 무거운 연산 최적화 예시

먼저 무거운 연산을 최적화하는 예시를 통한 useMemo 사용 전후 차이를 보여드리겠습니다.

가벼운 작업 버튼 - 바로 실행
무거운 작업 버튼 - 987654321번 for문 실행(1초 이상 소요)

비최적화 방식에서는 가벼운 작업 버튼만 눌러도 무거운 작업이 같이 실행되는 문제가 발생합니다.

 

왜 이러한 문제가 발생할까요 ?

노란 박스에 있는 코드를 보시면 setLightWork를 통해 가벼운 작업 상태만 변경했는데도

컴포넌트 전체가 재렌더링되면서 heavyWorkResult와 lightWorkResult가 다시 계산됩니다.

이때, heavyWork가 불필요하게 작동되어 가벼운 작업 또한 느려집니다.

이처럼 무거운 연산이 불필요하게 실행되는 것을 막기 위해 useMemo를 사용해 볼 수 있습니다.

 

아래는 useMemo를 사용한 결과입니다.

 

이처럼 가벼운 작업 버튼을 누르면 불필요한 연산이 수행되지 않고 바로 가벼운 작업의 결과가 보이는 것을 확인해 볼 수 있습니다.

 

아래와 같은 코드를 통해 useMemo의 사용법을 확인해 보실 수 있습니다.

이제는 더 이상 가벼운 작업 수행 시 무거운 작업(heavyWork)이 재실행되지 않습니다. 

무거운 작업의 값이 변경되지 않았기 때문에 이전의 값을 가져와 사용하게 되는 것입니다.

function UseMemoVersion() {
  const [heavyTodo, setHeavy] = useState(0);
  const [lightTodo, setLight] = useState(0);

  // heavyTodo가 바뀔 때만 heavyWork 실행
  const heavyWorkResult = useMemo(() => heavyWork(heavyTodo), [heavyTodo]);
  const lightWorkResult = useMemo(() => lightWork(lightTodo), [lightTodo]);

  ...
}

 

3. 예제로 보는 useMemo : useEffect + 객체 참조 안정화

이번에는 useEffect에서 객체 참조 때문에 발생하는 불필요한 실행에 대해 보겠습니다.

상태 : 글씨 크기, 테마(isDark)
목표 : 테마 버튼을 눌렀을 때만 콘솔 로그 출력

 

 

 

 

 

(1) 비최적화 버전

const darkMode = { mode: isDark ? 'DARK' : 'LIGHT' };

useEffect(() => {
  console.log('다크/라이트 모드 변경:', darkMode.mode);
}, [darkMode]); // fontSize 변경에도 실행됨

- 매 렌더마다 새로운 객체 생성

- 참조가 달라져 글씨 크기만 조절해도 콘솔 로그 출력

 

(2) useMemo 적용 버전

const darkMode = useMemo(
  () => ({ mode: isDark ? 'DARK' : 'LIGHT' }),
  [isDark]
);

useEffect(() => {
  console.log('다크/라이트 모드 변경:', darkMode.mode);
}, [darkMode]);

- isDark 변경 시에만 객체 참조 변경

- 글자 크기 변경 시에는 useEffect 작동 X

 

useMemo의 핵심을 다시 한번 정리해 보며 마무리하겠습니다.
- useMemo는 값의 재계산을 최소화하여 성능을 최적화
- 무거운 연산이나 참조 안정성이 필요한 경우에 특히 유용
- 남용하면 오히려 성능이 떨어질 수 있으므로, 실제 성능 문제가 있는 부분에만 사용

 

'FRONTEND > React' 카테고리의 다른 글

리액트 훅 | useContext에 대해 알아보기  (1) 2025.08.18
리액트 훅 | useActionState에 대해 알아보기  (3) 2025.08.14
리액트 훅 | useCallback에 대해 알아보기  (8) 2025.08.12
리액트 훅 | useEffect에 대해 알아보기  (5) 2025.08.11
리액트 훅 | useState에 대해 알아보기  (4) 2025.08.08
'FRONTEND/React' 카테고리의 다른 글
  • 리액트 훅 | useContext에 대해 알아보기
  • 리액트 훅 | useActionState에 대해 알아보기
  • 리액트 훅 | useCallback에 대해 알아보기
  • 리액트 훅 | useEffect에 대해 알아보기
uoaheu
uoaheu
uoaheu 님의 블로그 입니다.
  • uoaheu
    uoaheu 님의 블로그
    uoaheu
  • 전체
    오늘
    어제
    • 분류 전체보기 (50)
      • 알고리즘 (7)
      • CS (9)
      • FRONTEND (9)
        • React (12)
        • Kotlin (1)
        • JS (5)
        • HTML (2)
      • SQL (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    BFS
    toss 분석
    토스 앱 분석
    리액트usestate
    부트캠프후기
    이더넷프레임
    토스 uiux
    toss uiux
    mysql로 피벗테이블만들기
    엘지유플러스유레카프론트엔드
    알고리즘
    멀티캠퍼스it부트캠프
    유레카3기
    boj25418
    토스분석
    useactionstate
    혼자서 공부하는 네트워크
    mysql 피벗테이블
    mysql
    백준1926번
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
uoaheu
리액트 훅 | useMemo에 대해 알아보기
상단으로

티스토리툴바