본문 바로가기
개발

useMemo를 사용해서 불필요한 연산 줄이기

by 양현정 2023. 5. 6.

React 함수 컴포넌트는 렌더링이 일어날 때마다 컴포넌트 내부의 코드가 처음부터 다시 실행됩니다.
따라서 컴포넌트 안에서 변하지 않는 값이나 복잡한 연산을 매번 다시 계산하는 경우가 생기는데, 이것은 비효율적인 성능 저하를 초래할 수 있습니다.

문제 상황

예를 들어, 특정 문자열을 입력받아 검색하는 컴포넌트가 있다고 가정해 봅시다.

// 특정 문자열을 검색하는 컴포넌트
const [word, setWord] = useState<string>('');

const categories = (filterData.data?.class || [])
  .filter((category) => category.id === SearchInfo.CATEGORY)
  .map((category) => category.contents)
  .flat();

<SearchInput value={word} onInput={(e) => setWord(e.currentTarget.value)} />

 

위 코드에서 입력창에 문자열을 입력할 때마다 컴포넌트가 다시 렌더링되며, categories 변수에 들어가는 카테고리 데이터도 매번 재계산됩니다. 하지만 실제로는 입력값만 변경되고 카테고리 데이터는 변하지 않기 때문에, 불필요한 계산이 반복되는 셈이죠.


해결법: useMemo() 활용하기

이럴 때 useMemo() 훅을 사용하면 계산 결과를 메모이제이션(기억)하여, 의존성 배열에 포함된 값이 변할 때만 다시 계산하고 그렇지 않으면 이전 값을 재사용할 수 있습니다.

const [word, setWord] = useState<string>('');

const categories = useMemo(() => {
  return (filterData.data?.class || [])
    .filter((category) => category.id === SearchInfo.CATEGORY)
    .map((category) => category.contents)
    .flat();
}, [filterData.data?.class]);

<SearchInput value={word} onInput={(e) => setWord(e.currentTarget.value)} />

useMemo의 사용법은 useEffect와 비슷하며, 의존성 배열에 변화가 있을 값만 넣어주면 됩니다.
이렇게 하면 word가 바뀌어도 categories는 다시 계산되지 않아 불필요한 연산을 줄일 수 있습니다.

 

정리

  • React 함수 컴포넌트는 렌더링 시 내부 코드가 매번 실행되어 비효율적일 수 있다.
  • 변하지 않는 값이나 복잡한 계산 결과는 useMemo()를 이용해 메모이제이션하면 성능을 최적화할 수 있다.
  • useMemo는 의존성 배열에 지정된 값이 변할 때만 다시 계산한다.
  • 이를 통해 불필요한 연산과 렌더링 비용을 줄이고, 사용자 경험을 개선할 수 있다.