React.js: useMemo();

안녕하세요. 오늘은 React.js의 Hook 중에서 useMemo에 대해 살펴보겠습니다.

우선 이 Hook은 메모제이션된 값을 반환하는데, 메모제이션이 무엇일까요?
동일한 계산을 반복할 때 이전에 계산한 값을 메모리에 저장해서 동일한 계산의 반복수행을 배제하여 프로그램 실행 속도를 빠르게 해주는 기술입니다.

감이 올수도 있고 안 올수도 있는데, 반복된 계산을 제거해주면 어떤 일이 일어나게 될까요? 바로 렌더링이 빨라지게 됩니다.

리액트 공식문서에서 다음과 같이 말하고 있습니다.

“생성(create)” 함수와 그것의 의존성 값의 배열을 전달하세요. useMemo는 의존성이 변경되었을 때에만 메모이제이션된 값만 다시 계산 할 것입니다. 이 최적화는 모든 렌더링 시의 고비용 계산을 방지하게 해 줍니다.

예시를 위해서 다음과 같은 코드를 작성해보면,

import React, { useState } from "react";

const getAverage = (nums) => {
  console.log("Calculating Average");
  if (nums.length === 0) return 0;
  const sum = nums.reduce((x, y) => x + y);
  return sum / nums.length;
};

const Average = () => {
  const [valueList, setValueList] = useState([]);
  const [num, setNum] = useState("");

  const onChange = (e) => {
    setNum(e.target.value);
  };

  const onInsert = () => {
    const nextValueList = valueList.concat(parseInt(num));
    setValueList(nextValueList);
    setNum("");
  };

  return (
    <div>
      <input value={num} onChange={onChange} />
      <button onClick={onInsert}>Add</button>
      <ul>
        {valueList.map((value, index) => (
          <li key={index}>{value}</li>
        ))}
      </ul>
      <div>Average: {getAverage(valueList)}</div>
    </div>
  );
};

export default Average;

실행시켰을 때 콘솔에는 다음과 같이 동일작업이 반복수행 되는 것을 볼 수 있습니다.


단순한 값을 계산하는데는 크게 문제가 안되겠지만 계산과정이 매우 많고 복잡하다면 이는 비효율적일 수 있습니다.

그러면 useMemo Hook을 사용해서 어떻게 최적화를 할 수 있을까요?

useMemo Hook은 다음과 같은 기본꼴을 갖습니다.

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

자, 그러면 우리가 작성한 코드에서 computeExpensiveValue에 해당하는 것과 값의 리스트에 해당하는 것을 찾아서 대입해주면 되겠죠?

const memorizedValue = useMemo(() => getAverage(valueList), [valueList]);

return위에 추가해줍시다.

그리고 return에서 getAverage(valueList)memorizedValue로 수정해줍시다.

이 Hook을 사용하게 되면 계산을 할 때만 console에 메시지가 찍히는 것을 볼 수 있습니다.

이제 list 배열의 내용이 바뀔 때만 함수가 호출되게 됩니다.

포스팅 마칩니다.

좋은 웹페이지 즐겨찾기