본문 바로가기
카테고리 없음

[react] useMemo Hook + 예제

by 1two13 2023. 4. 27.
728x90
반응형

Memoization


Memoization은 저장해 둔 값을 활용하는 테크닉입니다.

함수 컴포넌트는 근본적으로 함수이고, 리엑트는 매 렌더링마다 함수 컴포넌트를 다시 호출합니다.

함수는 기본적으로 이전 호출과 새로운 호출 간에 값을 공유할 수 없기 때문에 만약 특정한 함수 호출 내에서 만들어진 변수를 다음 함수 호출에도 사용하고 싶다면 그 값을 함수 외부의 특정한 공간에 저장해 뒀다가 다음 호출 때 명시적으로 다시 꺼내와야 합니다.

 

이러한 과정을 리엑트에서는 API로 제공해주고 있고, 그것이 바로 useMemo입니다.

 

 

useMemo의 탄생 배경


리엑트 컴포넌트는 props와 state 값이 변경될 때마다 다시 렌더링됩니다. 때문에 props나 state에 의존하는 함수의 반환 값이 매번 계산되어야 할 경우, 불필요한 계산이 발생하여 성능 저하가 일어날 수 있습니다.

 

이런 경우, useMemo를 사용하면 함수의 반환 값을 기억하고, 이전 값과 비교하여 동일한 경우 이전 값으로 재사용할 수 있기 때문에 컴포넌트의 성능을 최적화할 수 있습니다.

 

useMemo는 아래와 같은 상황에서 사용할 수 있습니다.

  • 계산량이 많은 함수의 반환 값을 캐시하고, 성능을 최적화하는 경우
  • 특정 props나 state 값이 변경될 때만 계산을 수행하는 경우
  • 자주 호출되지만, 반환 값이 바뀌지 않는 경우

 

useMemo Hook


// useMemo(callbackFunction, deps]

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

useMemo의 첫 번째 파라미터에는 어떻게 연산할지 정의하는 함수를 넣어주면 되고, 

두 번째 파라미터에는 의존성 배열을 넣어주면 됩니다.

 

배열 안에 넣은 내용이 바뀌면, 첫 번째 파라미터에 등록한 함수를 호출해서 값을 연산해 주고,

만약에 내용이 바뀌지 않았다면 이전에 연산한 값을 재사용하게 됩니다.

 

 

예제


해당 링크에서 코드를 직접 확인해볼 수 있습니다. 

import React, { useMemo, useState } from 'react';

function Example({ data }) {
  const [sortOrder, setSortOrder] = useState('asc');

  const sortedData = useMemo(() => {
    console.log('useMemo');
    // 배열을 정렬하는 함수
    return data.sort((a, b) => {
      if (sortOrder === 'asc') {
        return a.value - b.value;
      } else {
        return b.value - a.value;
      }
    });
  }, [data, sortOrder]);

  return (
    <div>
      <button
        onClick={() =>
          setSortOrder((sort) => (sort === 'asc' ? 'desc' : 'asc'))
        }
      >
        {sortOrder === 'asc' ? 'Sort Desc' : 'Sort Asc'}
      </button>
      <ul>
        {sortedData.map((item) => (
          <li key={item.id}>{item.value}</li>
        ))}
      </ul>
    </div>
  );
}

export default Example;

useMemo를 사용하면, 2번째 인자로 전달해 준 data와 sortOrder 값이 변경될 때만 배열 정렬 함수를 실행할 수 있습니다. 

이를 통해 성능을 최적화하고, 정렬 순서가 변경되지 않은 경우에는 이전에 계산한 값을 재사용할 수 있습니다.

 

useMemo를 사용하지 않는다면 sortedData를 매 렌더링마다 다시 계산하게 되어 성능 문제가 발생할 수 있습니다.

 

 

참고자료



질문이나 잘못된 점은 댓글로 남겨주세요 :)💖

728x90
반응형

댓글