hooks-useMemo

❓What is useMemo

  • 컴포넌트 최적화에 사용되는 대표적인 훅이며, 비슷한 훅으로는 useCallback이 있다.

  • memo란? Memoization 을 뜻한다.

  • 동일한 값을 리턴하는 함수를 반복적으로 호출해야 할 때, 가장 처음에 사용했던 값을 메모리에 저장한다.

  • 즉, 자주 사용되는 을 필요할 때 마다 캐시에서 가져와서 사용하는 것이다.

  • 함수형 컴포넌트는 상태가 변경될 때 마다 리렌더링되고, 그 때 마다 내부 변수가 초기화된다.

  • 꼭 필요할 때만 적절하게 사용하는 것이 성능에 좋다.

예제 코드

function loadSomeData(value: number): number {
  for (let i = 0; i < 999999999; i++) {}
  return value;
}

export default function Hello() {
  const [countA, setCountA] = useState(0);
  const [countB, setCountB] = useState(0);

  const result = loadSomeData(countA);

  return (
    <div>
      <div>countA: {result}</div>
      <div>countB: {countB}</div>
      <div>
        <input
          type='number'
          value={result}
          onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
            setCountA(Number(e.target.value))
          }
        />
      </div>
      <div>
        <input
          type='number'
          onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
            setCountB(Number(e.target.value))
          }
        />
      </div>
    </div>
  );
}
  • 컴포넌트가 렌더링되자마자 loadSomeData 함수가 실행되고 딜레이가 걸린다.

  • 2개의 인풋 값 중에 어떤 것을 업데이트 하더라도 loadSomeData 함수가 실행되어 딜레이가 걸린다.

  • 위의 코드에서는 useMemo 를 사용하여 loadSomeData 함수에 대한 값을 메모이제이션하도록 수정한다.

  • 그러면 두번째 input 값은 딜레이 없이 변경이 가능하다.

  • 즉, loadSomeData 함수의 리턴 값이 된 countA useMemo의 의존성배열에 설정하여 같은 컴포넌트 내에서 다른 상태 값이 변경이 되어도, countA의 값은 변경되지 않아 딜레이가 발생하지 않는다.


값이 아니라 객체라면?

  • 상태 값이 2개가 있다. 하나는 원시값을 갖는 count, 또 다른 하나는 user 라는 객체

  • user 객체의 키 값을 추가하여 리턴하도록 하고, useEffect를 추가하여 의존성배열에 nameAndAge 설정

  • 이렇게 했을 때 기대하는 동작은, user 의 값이 바뀌었을 때만 useEffect가 호출되고, count 값이 바뀌없을 떄는 useEffect가 호출되지 않아야 한다.

  • 그러나 useEffect 는 count 값이 바뀌던지 user 객체의 값이 바뀌던지 언제나 호출된다.

  • 즉, nameAndAge 라는 객체가 매번 새롭게 생성되기 때문이다.

아래의 코드와 같이 수정하자.

이렇게 하면 user 의 name 값이 useMemo의 의존성배열에 설정되어, useEffect는 user의 name 값이 변경될 때에만 실행되게 된다.

Last updated