본문 바로가기
FE/React

memoization(feat. useMemo, useCallback)

by ideal_string 2022. 10. 26.

메모이제이션(memoization)은 동일한 계산을 반복해야 할 때 이전에 계산한 값을 메모리에 저장해 동일한 계산의 반복 수행을 제거함을 뜻한다. 이는 프로그램 실행 속도를 빠르게 하는 기술이며, 복잡한 문제를 간단한 여러 문제로 나누어 푸는 동적 계획법의 핵심이 되는 기술로 알려져 있다.

 

리액트에서 메모이제이션은 최적화의 동의어다. 처음 렌더링 후 다음에 리렌더링 되었을 때 값이 바뀌지 않았다면 다시 계산해 새로 그리지 않고 기존 값을 그대로 내놓기 때문. 컴퓨터가 다시 계산하지 않고 바로 결과값을 나타내니 사용자 입장에선 굉장히 빠른 피드백을 받는 듯하다. 리액트 훅 useMemo를 통해 간단히 살펴볼 수 있다.

const aaa = Math.random();
console.log(aaa);

const bbb = useMemo(() => Math.random(), []);
console.log(bbb);

위와 같이 랜덤 함수를 생성해 콘솔에 출력한다면? 항상 새로운 수가 나타난다. 다만 bbb처럼 useMemo를 사용하면 렌더링 시 처음 생성된 랜덤 수가 리렌더링이 된다해도 같은 수가 계속 찍힌다. 

import { useCallback } from "react";

export default function MemoizationParentPage() {
  let countLet = 0;

  // useCallback으로 함수 기억
  const onClickCountLet = useCallback(() => {
    console.log(countLet + 1);
    countLet += 1;
  }, []);

  return (
    <>
      <div>카운트(let) : {countLet}</div>
      <button onClick={onClickCountLet}>카운트(let) +1 올리기</button>
    </>
  );
}

useCallback으로 함수를 기억시킬 수 있다 다만. 여기서도 변수 값을 기억하기 때문에 의도대로 잘 작동하는 지 점검할 필요가 있다. 카운트 올리는 함수를 만들고 해당 값을 화면과 콘솔에 각각 출력했다. 똑같이 스코프 밖에 있는 countLet을 가져왔음에도 콘솔에 있는 값은 늘어난 반면, useCallback 안에서 직접 사용한 countLet은 기존 값을 기억해 처음 값인 0을 계속 출력하고 있다.

import { useCallback, useState } from "react";
export default function MemoizationParentPage() {
  const [countState, setCountState] = useState(0);

  const onClickCountState = useCallback(() => {
    setCountState(countState + 1); // 스테이트 1 올라간 후 해당 값을 기억해 계속 1을 출력 
    setCountState((prev) => prev + 1); // 따라서 prev를 통해야 값을 계속 반영할 수 있음.
  }, []);


  return (
    <>
      <div>카운트(state) : {countState}</div>
      <button onClick={onClickCountState}>카운트(state) +1 올리기</button>
    </>
  );
}

useState를 사용할 경우 state의 값도 기억하기 때문에, useCallback 혹은 useMemo와 useState를 사용한다면 주의할 필요가 있다.

 

※ 잘못된 내용이 있을 경우 댓글로 알려주세요. 배우고 익히고 수정하겠습니다:)

'FE > React' 카테고리의 다른 글

coustom hook보다 일반 function이 나을 수도 있다.  (0) 2023.01.19
useForm handleSubmit이 동작하지 않는다.  (0) 2022.12.12
Curring  (0) 2022.10.26
Optimistic-UI  (0) 2022.10.25
Shallow Routing  (0) 2022.10.25