본문 바로가기
Frontend

[React] useMemo와 useCallback

by 구라미 2024. 1. 19.

 

 

 

React로 개발하다보면 많이 들어봤을 useMemo와 useCallback은 성능최적화를 위해 사용되는 hook인데, 적재적소에 잘 활용하면 불필요한 리렌더링, 함수 재생성을 방지할 수 있지만 무분별하게 사용한다면 오히려 성능최적화에 방해가 될 수 있다. 

그렇다면 useMemo와 useCallback이 무엇이고, 언제 사용해야 하며 언제 사용하면 안되는 걸까?

 

1. useMemo란?

React에서 제공하는 hook 중 하나로 계산비용이 높은 연산결과를 메모이제이션하여, 불필요한 연산을 최소화하는 hook이다. 
useMemo를 사용해서 결과값을 캐싱하면 렌더링 중에 값이 한번만 계산이 되며 이 후에 렌더링할 경우 의존성배열의 값이 달라지지 않는다면 이 전에 연산했던 값을 그대로 재사용한다.

React에서 import해서 다음과 같이 사용한다.

const memoized = useMemo(() => {
	computeExpensiveValue(val1, val2)
}, [val1, val2]);

[val2, val2] 이 부분이 useMemo hook을 사용시 넘겨주는 의존성 배열부분인데 이 배열의 값이 변경되지 않는 한 캐싱되어있던 값을 재사용한다. 

 

2. useMemo를 사용하면 좋은 경우

  • 배열이나 객체를 가공할 때
  • 복잡한 계산을 수행해야할 때
  • API 호출해서 데이터를 가져올 때

 

3. useMemo를 사용하면 안되는 경우

  • 메모이제이션 했을 시 유의미한 성능개선이 있지 않을 때
  • 의존성 배열에 완전히 새로운 객체나 배열이 전달되는 경우 -> 의존성이 같지 않으므로 메모이제이션이 불필요하다

 

4. useCallback이란?

useCallback도 React에서 제공하는 hook 중 하나인데, 이것은 함수를 메모이제이션한다. 이전에 한번 생성된 함수를 기억해서 불필요하게 함수가 재생성되는 것을 방지한다.

const TestComponent = () => {
  const [number, setNumber] = useState(0);

  const increaseNumber = useCallback(() => {
    number++;
  }, [number]);

  return (
    <div>
      <button onClick={increaseNumber}>+</button>
    </div>
  );
};

위와같은 경우 의존성배열의 number 의 상태값이 변경되지 않는다면 이 이전에 생성된 후 메모이제이션 되었던 함수가 재사용된다. 콜백함수를 최적화하는데 사용하는 hook이다.

 

5. useCallback을 사용하면 좋은 경우

  • 컴포넌트에 전달되는 Callback 함수일 때
  • 자주 호출되는 Callback 함수일 때
  • 렌더링 성능이 최적화된 자식 컴포넌트(React.memo로 감싼 컴포넌트)에 함수를 props로 넘겨주는 경우
  • 큰 비용을 필요로하는 함수를 생성할 때

 

6. useCallback을 사용하면 안되는 경우

  • 단순 함수 내에서 상태를 변경하는 setState나 dispatch를 사용하는 경우
  • 함수가 단순한 연산일 경우 -> 오히려 더 많은 비용이 든다.

 

댓글