1 분 소요

1. useMemo

useMemo에서 Memo라는 말은 Memoization을 뜻한다. 메모이제이션이란 동일한 값을 리턴하는 함수를 반복적으로 호출해야 한다면 맨 처음 값을 계산할 때 해당 값을 메모리에 저장해서 또 다시 계산하지 않고 필요할때마다 메모리에서 꺼내서 재사용하는 기법을 말한다. 더 간단히 말하자면 자주 필요한 값을 맨 처음 계산 할 때 캐싱을 해둬서 그 값이 필요할 때마다 캐시에서 꺼내서 사용하는 것이다.

function Component() {
  const value = calculate();
  return <div>{value}</div>;
}

위의 예제를 보자.

value는 calculate() 함수로 부터 값을 받아온다. 대부분의 리액트 컴포넌트는 state props의 변화로 인해 수많은 렌더링을 거친다. 컴포넌트가 렌더링 될때마다 value가 초기화되기 때문에 calculate() 함수는 반복적으로 호출될 것이다. 만약 calculate() 함수가 매우 무거운 작업을 하는 함수라면 굉장히 비효율적일 것이다. 왜냐하면 무의미한 계산을 반복해서 value라는 변수에 같은 값을 반복적으로 할당하고 있기 때문이다.

이때 useMemo를 사용해서 Memoization 을 해주면 이 상황을 간편하게 해결할 수 있다.

function Component() {
  const value = useMemo(() => calculate(), []);

  return <div>{value}</div>;
}

useMemo는 처음에 계산된 결과값을 메모리에 저장해서 컴포넌트가 반복적으로 렌더링되어도 calculate를 다시 호출하지 않고 이전에 이미 계산된 결과값을 메모리에서 꺼내와서 재사용할 수 있게 해준다.

2. useMemo의 구조

const value = useMemo(() => {
  return calculate();
}, [item]);

useMemo는 두개의 인자를 받는다. 첫번째 인자로는 콜백함수, 두번째 인자로는 배열을 받는다.

첫번째 인자인 콜백함수는 우리가 메모이제이션 해줄 값을 계산해서 리턴해주는 함수이다. 이 콜백함수가 리턴하는 값이 바로 useMemo가 리턴하는 값이 되는 것이다.

두번째 인자인 배열은 의존성 배열이라고도 불린다. useMemo는 배열안의 값이 업데이트 될때만 콜백함수를 다시 호출해서 메모이제이션된 값을 업데이트해서 다시 메모이제이션을 해준다. 만약에 빈배열을 넘겨주면 맨 처음 컴포넌트가 마운트 되었을 때만 값을 계산하고 이후에는 항상 메모이제이션된 값을 꺼내와서 사용한다.

3. 꼭 필요할 때만 사용하자!

useMemo도 남용하게 되면 오히려 성능에 무리가 갈 수 있다. useMemo를 사용한다는 건 값을 재활용하기 위해서 따로 메모리를 소모해서 값을 저장해 둔다는 것인데 이는 불필요한 값들까지 모두 메모아이즈 해버리면 오히려 성능이 악화될 수 있다. 그렇기 때문에 useMemo는 필요할 때만 적절하게 사용하는 것이 중요하다.

4. useMemo 사용 방법

객체 타입의 데이터는 메모리 안에 보관이 되고 변수에는 객체의 주소가 보관된다. 똑같아 보이는 변수가 담겨있는 객체를 비교해보면 안에 내용이 같아도 주소가 다르기 때문에 다르다는 결과값이 나온다.

자바스크립트는 컴포넌트가 리렌더 되면 똑같아 보이는 location 객체여도 참조하고 있는 주소가 바꼈기 때문에 location에 새로운 객체가 다시 할당되었다고 생각한다. 그런데 다른 state가 변경되어도 컴포넌트는 리렌더 되기 때문에 useEffect와 객체타입을 같이 사용하는 것은 좋지않다.

이럴 때 useMemo를 사용하면 컴포넌트를 최적화 시킬 수 있다.


본 글은 별코딩 영상을 보고 작성한 글입니다!

댓글남기기