본문 바로가기
공부한것/React

[React] useMemo, memoization 공부하기!

by flyda 2022. 8. 3.

react

 

이 글은 별코딩의 React Hooks에 취한다 - useMemo 제대로 사용하기 | 리액트 훅스 시리즈영상을 정리한 글입니다. 

1. useMemo

1-1. 기본개념

useMemo와 useCallback은 컴포넌트 최적화를 위해서 사용한다. 

useMeno에서 Memo는 memoization에서 온 말이다. 동일한 값을 리턴하는 함수를 반복적으로 호출할 때 처음 값을 계산할 때 그 값을 메모리에 저장해서 다음 호출에서 다시 계산하지 않고 재사용하는 기법을 말한다. 처음 계산할 때 그 값을 캐싱해둬서 필요할 때마다 캐시에서 꺼내서 사용하는 것이다. 

함수형 컴포넌트는 함수이다!! 즉 렌더링이될때 component함수가 호출되고 모든 내부 변수가 초기화된다. 만약 무거운 작업을 하는 함수가 component가 렌더링이 될 때마다 계속해서 호출되어야 한다면 성능에 좋지 않다. 이때  useMemo를 사용할 수 있다. 

렌더링component 함수 호출, Memoization 렌더링component 함수 호출, Memoize된 값 재사용

 

1-2. useMemo의 형태 

  const value = useMemo(() => {
    return calculate();
  }, [item])
  •  콜백함수 : memoization 해야하는 값을 계산해서 return 하는 함수  
  • 배열 : (의존성 배열) 배열 속의 값이 업데이트될 때만 콜백 함수를 다시 호출해서 memoization 된 값을 다시 memoization 하고 리턴해준다. 만약 빈 배열을 넘겨주면 처음에 컴포넌트가 처음 mount 되었을 때만 값을 계산하고 이후에는 항상 memoization 된 값을 꺼내와서 사용하게 된다!

꼭 필요할 때만 사용하기!! 무분별하게 남용하면 성능에 좋지 않음.! 따로 메모리를 사용해서 저장해두는 거라서 불필요한 것도 다 저장하면 성능이 악화될 수 있다. 

 

2. 실습

2-1. useMemo 사용하기 

시간이 많이 걸리는 로직을  useMemo를 사용해서 저장해두는 실습! 

더보기

cf) 만약 stackBliz나 리액트 프로젝트에서 처음에 두번 렌더링이 된다면 이 글을 참고하기를 바란다! 2022.08.04 - [핀테크 서비스 프론트엔드 개발자 취업 완성 2기/React] - [React] 프로젝트에서 계속 두 번씩 렌더링 되는 현상 해결하기

 

2-2. useMemo가 유용한 상황

 

이 예제에서 useEffect의 의존성 배열에 location이 원시타입(String)이라서  location이 변경되었을 때 useEffect가 변경이 된다..!! 하지만 의존성 배열에 전달해 주는 값이  string과 같은 원시타입이 아니라 object라면 다르다!

기존의 코드의 경우 number가 증가해도 다시 렌더링되지 않았는데, 객체타입인 경우  number가 증가해도 다시 렌더링이 되는 것을 볼 수 있다. 

cf) 원시(primitive)타입 vs 객체(Object)타입

더보기
  • 원시(primitive)타입
    • String, Number, Boolean, Null, Undefined, BigInt, Symbol
  • 객체(Object)타입
    • Object, Array 등등 (원시타입을 제외한 모든 것)
원시형, 참조(객체)타입 변수의 차이점!! heropy강사님의 수업에서 캡쳐한 이미지입니다!!

 

https://youtu.be/e-CnI8Q5RY4 캡쳐!!

즉 객체데이터(참조형데이터)는 참조형데이터가 저장된 주소를 비교하게 되는데, 다른 주소를 비교하는 것이기 때문에 당연히 false가 나온다!

number를 증가시키면 함수 컴포넌트가 다시 실행이되고 location객체는 보기에는 같은 값이지만 다시 객체 할당을 받게 된다. 즉 같은 값이지만 다른 메모리상의 공간에 저장이 되는 것!! 그래서 useEffect는 우리가 보기에는 같은 값이라도 location이 참조하고 있는 주소가 변경되었기 때문에 location값이 바뀌었다고 생각하고 다시 렌더링을 하는 것이다!! 

이 문제를 해결하기 위해서는 이 컴포넌트가 다시 렌더링이 되었을 때 다시 초기화 되는 것을 막아줘야한다. 이때 useMemo를 사용하는 것!! (대박..!)

 이 실습 코드 처럼...!!! useMemo를 사용해서 객체가 컴포넌트가 렌더링될 때마다 초기화 되서 다시 할당되는 것을 막을 수 있다!!! 대박!!! 

댓글