본문으로 바로가기

[React] useMemo 사용법 및 예제

category 1. 웹개발/1_1_5 React JS 2022. 4. 6. 22:15

[useMemo]

useMemo는 컴포넌트의 성능을 최적화시킬 수 있는 대표적인 react hooks 중 하나입니다. useMemo에서 Memo는 Memoization을 뜻합니다. memoization이란 기존에 수행한 연산의 결괏값을 어딘가에 저장해 두고 동일한 입력이 들어오면 재활용하는 프로그래밍 기법을 말합니다. 

 

 

먼저 시작하기 전에 함수형 컴포넌트에 대해 꼭 아셔야 합니다. 아래 예제를 보면서 같이 살펴보겠습니다. 함수형 컴포넌트는 렌더링 ➡️ Component 함수 호출 ➡️ 모든 내부 변수 초기화의 순서를 거칩니다. Component가 렌더링이 될 때마다 value라는 변수가 초기화됩니다. 따라서 calculate 함수는 반복적으로 호출됩니다. calculate 함수가 무거운 일을 하는 함수라면 굉장히 비효율적이겠죠? 무거운 일을 반복적으로 하니깐요.

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

function calculate() {
    return 10;
}

 

 

useMemo를 사용하면 렌더링 ➡️ Component 함수 호출 ➡️ Memoize된 함수를 재사용하는 동작 순서를 거칩니다. useMemo를 사용해서 memoization을 해주면 calculate 함수를 반복적으로 실행할 필요 없습니다. useMemo는 처음에 계산된 결괏값을 메모리에 저장해서 컴포넌트가 반복적으로 렌더링이 되어도 계속 calculate를 다시 호출하지 않고 이전에 이미 계산된 결과 값을 메모리에서 꺼내와서 재사용할 수 있게 해 줍니다.

 

 

useMemo는 첫 번째 인자로 콜백 함수를, 두 번째 인자로 의존성 배열을 받습니다. 두 번째 인자인 배열의 요소 값이 업데이트될 때만 콜백 함수를 다시 호출해서 memoization 된 값을 업데이트 해줘서 다시 memoization을 해줍니다. 만약에 빈 배열([])을 넘겨주면 맨 처음 컴포넌트가 마운트 되었을 때만 값을 계산하고 이후에는 항상 memoization된 값을 꺼내 와서 사용합니다.

// 첫 번째 인자 콜백함수 
// 두 번째 인자 의존성배열
const value = useMemo(() => {
    return calculate();
},[item])

 

* 꼭 필요할 때만 사용

값을 재활용하기 위해 따로 메모리를 소비해서 저장을 해놓는 것입니다. 그렇기 때문에 불필요한 값을 모두 Memoization 해버리면 성능이 안 좋아질 수 있기 때문에 필요할 때만 사용하도록 합니다.

 

 

[Import]

react Hooks의 useMemo를 사용하기 위해서는 react에서 useMemo를 import 받아야 합니다.

import { useMemo } from 'react';

 

 

[예제]

object는 객체 타입이어서 일반 원시 타입과는 다르게 값이 저장될 때 주소 값으로 저장이 됩니다. 즉, 메모리 상의 주소가 다르게 저장되어 있는 것입니다.  const location = { country: isKorea ? '한국' : '일본' }; 눈으로 보이기에는 똑같지만 저장된 메모리 상의 주소가 완전히 다르기 때문에 useEffect의 location은 변경이 되었다고 생각할 수 있습니다. 

const location = { country: isKorea ? '한국' : '일본' };

useEffect(() => {
    console.log('useEffect... 호출');
}, [location])

 

 

따라서 이것을 해결해주려면 useMemo를 아래와 같이 사용해서 memoization 해주시면 됩니다.

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

function App() {
  const [number, setNumber] = useState(0);
  const [isKorea, setIsKorea] = useState(true);
  
  // const location = { country: isKorea ? '한국' : '일본' };
  const location = useMemo(() => {
    return {
      country: isKorea ? '한국' : '일본'
    }
  }, [isKorea])

  useEffect(() => {
    console.log('useEffect... 호출');
    // 뭔가 오래 걸리는 작업
  }, [location])

  return (
    <header className="App-header">
        <h2>하루에 몇 끼 먹어요?</h2>
        <input type="number" value={number} onChange={(e) => setNumber(e.target.value)}/>
        <hr/>

        <h2>어느 나라에 있어요?</h2>
        <p>나라: {location.country}</p>
        <button onClick={() => setIsKorea(!isKorea)}>Update</button>
    </header>
  );
}

export default App;

 

[실행 화면]

 

 

Reference
react.org-hooks-useMemo

별코딩님의 useMemo 강의