main-logo

React useMemo를 사용해 보자

useMemo를 언제 사용해야 하고 왜 사용하는 걸까?

profile
1320129
2023년 02월 22일 · 0 분 소요

들어가며

최근 React를 사용하는 프로젝트가 많았는데요.
useEffect, useState라는 개념이 익숙해지고 사이트 최적화를 위해 useMemo 및 useCallback을 알게 되었습니다.
오늘은 useMemo를 같이 알아보아요!

useMemo를 배우기 전 알아야 할 사항


함수형 컴포넌트는 JSX를 리턴해주는 함수입니다.
함수형 컴포넌트의 렌더링이란 그 함수가 호출되어 실행하게 된다면 렌더링하게 된다고 말합니다.
또한 해당 컴포넌트의 State 값이 변경되거나 받는 Props 값이 변경된다면 해당 함수는 리 렌더링이 됩니다.
컴포넌트 안에는 변수 및 함수 및 하위 컴포넌트들로 구성되어 있을 수 있는데 리 렌더링이 될 때마다 초기화가 되어 다시 호출된다면 애플리케이션 성능이 매우 좋지 않아요.

 

image1.jpg

작가 macrovector 출처 Freepik

Memoization

useMemo에서 Memo는 Memoization을 뜻합니다.
Memoization는 값을 메모리에 저장하여 동일한 입력값이 들어온다면 저장한 값을 사용하는 프로그래밍 기법입니다.
React에서는 동일 값을 리턴해주는 함수를 반복적으로 사용하게 된다면 메모리에 저장하여 불필요한 계산을 막아주는 역할을 합니다.
예를 들자면 홈페이지에서 페이지 이동을 해도 로그인 상태가 유지되는 걸 생각하시면 편할 것 같아요!
페이지 이동할 때마다 매번 로그인해주어야 한다면 홈페이지 사용하는 데 시간이 매우 오래 걸리겠어요!

useMemo

useMemo(() => callbackFunction, [item]);

어떻게 사용하는지 같이 보아요!
useMemo는 인자를 2개 받습니다.
하나는 callbackFunction, 하나는 dependencies(의존성 배열)를 받습니다.
dependencies(의존성 배열)가 바뀐 값이 없다면 이미 계산되어 저장된 값을 리턴하고 바뀐 값이 존재한다면 새로 계산하게 됩니다.
기존 useEffect와 사용법이 매우 비슷하네요!

useMemo를 사용해보자!


글 설명은 눈에 잘 안 들어오시죠!
간단한 코드로 어떻게 사용하는지 같이 확인해 보아요!

 

image2.png

 

두 개의 인풋이 있습니다. 각 인풋은 onChange가 된다면
각각의 함수가 실행되게 했는데요.

//무거운 인풋 함수
const heavyFu = (text: string) => {
  console.log('무거운 함수 실행하면 진짜 느려요');
  return text;
};

//가벼운 인풋 함수
const lightFu = (text: string) => {
  console.log('가벼운 함수');
  return text;
};

 

image3.png

 

하지만 하나의 인풋만 onChange가 되어도 2개의 함수가 실행되는 걸 확인할 수 있습니다.
아까 설명해 드린 리 렌더링이 발생하고 있네요!
매번 불필요한 무거운 계산을 하는 함수가 실행된다면 홈페이지 기능에 매우 좋지 않아요.

useMemo 적용

  const completeHeavy = useMemo(() => {
    heavyFu(heavyValue as string);
  }, [heavyValue]);
  const completeLight = useMemo(() => {
    lightFu(lightValue as string);
  }, [lightValue]);

함수를 호출시키는 곳에 useMemo를 적용해 보았습니다. dependencies(의존성 배열)에는 각 값을 넣어주어 값의 변화가 감지된다면 새로 계산할 수 있게 사용했습니다!
콘솔을 다시 확인해 볼게요!

image4.png


정상적으로 바뀌는 인풋에 사용되는 함수만 실행해 주는 걸 확인해줄 수 있습니다!

마치며

프로젝트 규모가 커지면 커질수록 작업할 때 무거움을 자주 느꼈고 최적화는 이슈는 필수였는데요!
언제 사용해야 하고, 사용해야 하는 이유를 알게 된 것 같습니다!
다음 시간에는 useCallback을 같이 확인해 보아요!

참고문서