본문 바로가기

2주차

메모이제이션 - useCallback, useMemo + React.memo

안녕하세요, 웹파트 OB 공준혁입니다. 

 

요즘 리액트가 개편되면서, 자동으로 렌더링 효율성을 챙길 수는 있다고는 하나, 메모이제이션에 대한 개념을 알고는 있어야 한다.

💡 메모이제이션

:이전에 계산한 값을 기억하여 재계산을 방지하는 기술. 함수나 값의 결과를 캐싱하여 동일한 입력에 대해 동일한 출력을 반환하도록 만든다. 이는 성능 향상과 코드의 최적화에 도움이 된다.

 

즉, 메모이제이션은 말 그대로 “기억” 한다는 의미이다.

리액트에서는 컴포넌트 렌더링이 자주 일어나기 때문에, 불필요한 렌더링을 방지하기 위해

“기억”하는 기술을 사용하는 것이 종종 필요하다. 대표적으로 useCallback, useMemo가 있다!

use로 시작하는건 기본적으로 리액트 컴포넌트의 Hook이라고 생각하면 된다.

useCallback, useMemo 둘의 형식은 비슷하다. use~(콜백함수, 의존성배열);

1. useCallback

useCallback Hook은 메모이제이션된 콜백 함수를 반환한다.

이 훅은 주로 렌더링 성능을 최적화하고 불필요한 렌더링을 방지하기 위해 사용한다.

즉, 동일한 함수를 계속해서 재생성하는 것을 방지하여 불필요한 렌더링을 줄인다.

💡 참고로, 꼭 콜백 함수로 쓰이지 않아도 괜찮다. 바뀔 일 없는 함수의 선언 시에도 useCallback을 사용해도 된다.

 

아래의 경우 dependancy를 빈 배열로 두어서, 다시는 바뀌지 않을 것임을 공고히 한다.

따라서, Counter 컴포넌트가 몇번을 리렌더링 되어도, 함수의 선언 및 정의는 딱 1번만 일어난다.

import React, { useState, useCallback } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    setCount(prevCount => prevCount + 1);
  }, []);

  return (
    <div>
      <p>Count: {count}</p>
      {/* 메모이제이션이 적용된 콜백 함수를 이벤트 핸들러로 사용 */}
      <button onClick={handleClick}>Increment</button>
    </div>
  );
};

export default Counter;

2. useMemo

useMemo 훅은 메모이제이션된 을 반환한다.

이 값은 의존성 배열이 변경되지 않는 한 이전에 계산된 값을 사용한다.

이 훅은 주로 계산 비용이 높은 값을 캐싱하여 성능을 향상시키는 데 사용된다.

💡 참고로, useMemo를 받아와서 사용해도 되지만 React만 받아온 뒤, React.memo() 형태로 사용할 수도 있다.

 

useMemo를 통해, 컴포넌트내에서 계산 비용이 큰 (배열의 총합)값을 데이터 배열(dataArr)이 변하지 않는 한, 변하지 않도록 설정하여 최적화를 이뤘다.

import React, { useMemo } from 'react';

const ExComponent = ({ dataArr }) => {
  const memoizedValue = useMemo(() => {
    return dataArr.reduce((acc, curr) => acc + curr, 0); //총합을 구함
  }, [dataArr]);

  
};

export default ExComponent;

+ useMemo 와 React.memo 구분하기

💡 useMemo Hook : 메모이제이션된 을 반환.

 

💡 React.memo : 컴포넌트를 메모이제이션하여 렌더링 성능을 향상 props가 변경되지 않으면 이전에 렌더링된 결과를 재사용.

 

useMemo React.memo

렌더링 여부 영향 의존성 배열(dependancy) Props
메모이제이션 대상 컴포넌트
  1. useMemo를 사용하여 값을 메모이제이션.
//memoizedValue를 useMemo를 통해 설정함으로써, 
//a,b가 변하지 않으면 다시는 계산하지 않는다. (리렌더링 되어도)
const memoizedValue = useMemo(() => {
  // 계산 비용이 높은 작업 수행
  return computeExpensiveValue(a, b);
}, [a, b]);

  1. React.memo를 사용하여 컴포넌트를 메모이제이션
const MyComponent = React.memo((props) => {
  // 컴포넌트 렌더링
});

참고로, React.memo는

import React from 'react'; 

를 통해 React 객체에서 memo 메서드를 사용하는 방식이다.