Front-End/React

useMemo와 useCallback, React.memo 의 차이점

g_three 2023. 5. 5. 14:05


useCallback과 useMemo의 차이점

 결론 부터 말하자면 useCallback과 useMemo는 모두 컴포넌트를 최적화하기 위해 사용하는 Hook 이다. 

 

차이점은 useCallback은 함수를 캐싱하고, useMemo는 결과값을 캐싱한다. 

 

 

 

useCallback

useCallback은 함수를 기억하는 Hook으로 2개의 인자를 받는다.

 

첫번째 인자는 새로만들 함수의 내용이 들어오고, 

 

두번째 인자는 함수가 의존하는 값이 들어있는 배열이 들어온다. 

 

두번째 인자가 변경되지 않으면 기존의 함수를 재사용하게 된다. 

 

 

예를 들어 다음과 같은 코드가 있다.

function Example({ onClick }) {
  const handleClick = () => {
    console.log('button clicked');
    onClick();
  };

  return (
    <button onClick={handleClick}>Click me</button>
  );
}

handleClick 함수는 setCount 를 호출할때마다 새로운 함수를 생성한다. 

 

계속해서 함수를 생성하는 것을 방지하기 위해 useCallback을 사용한다. 

 

function Example({ onClick }) {
  const handleClick = useCallback(() => {
    console.log('button clicked');
    onClick();
  }, [onClick]);

  return (
    <button onClick={handleClick}>Click me</button>
  );
}

이렇게 사용한다면 이전에 만든 함수를 재사용한다.

 

 

 

useMemo

useMemo 역시 두개의 인자를 받는다.

 

첫번째 인자는 useCallback 과는 다르게 새로만들 함수가 아닌, 값을 생성하는 함수이다. 

 

두번째 인자는 useCallback과 마찬가지로 의존성 배열이 들어와 변경되는 것을 판단한다. 

 

 

useMemo는 Recat에서 값을 기억하는 방법으로 값을 생성할때마다 계산비용이 큰 작업이나, 컴포넌트의 상태나 속성에 따라 계산 결과 향상같은 경우, 불필요한 계산을 피하기 위해 기억하는 것이 좋다.

 

function Example({ list }) {
  const sortedList = useMemo(() => {
    return list.sort();
  }, [list]);

  return (
    <ul>
      {sortedList.map(item => (
        <li key={item}>{item}</li>
      ))}
    </ul>
  );
}

위 코드에서 useMemo는 sortedList 값을 생성하고, 이전에 생성된 값을 재사용한다. 

 

이전에 생성된 값을 재사용하면, list가 변경될때마다 매번 새로운 배열을 생성하는 것을 방지할 수 있다. 

 

 

React.memo

React.memo는 React에서 제공하는 고차 컴포넌트(Higher-Order Component)이다. 이를 사용하여 컴포넌트의 리렌더링을 최소화 할 수 있다.

 

React 컴포넌트가 리렌더링될 때, 해당 컴포넌트의 'props'나 'state'가 변경되면 React는 기본적으로 컴포넌트를 다시 렌더링한다. 그러나 때때로 컴포넌트의 'props'가 변경되더라도 컴포넌트 내부에서 처리해야 할 로직에 영향을 주지않는 경우가 있는데, 이럴때 'React.memo'를 사용하여 불필요한 렌더링을 방지할 수 있다.

 

const MyComponent = React.memo((props) => {
  // 컴포넌트의 내용
});

// 또는

const MyComponent = (props) => {
  // 컴포넌트의 내용
};

export default React.memo(MyComponent);

'React.memo'로 래핑된 컴포넌트는 이전에 렌더링된 결과를 기억하고, 이전 'props'와 현재 'props'를 비교하여 변경 여부를 판단한다. 만약 'props'가 동일하다면 이전에 렌더링된 결과를 재사용하여 불필요한 리렌더링을 방지한다. 

 

이를통해 컴포넌트의 성능을 최적화하고, 렌더링 성능에 불필요한 부하를 줄일 수 있다. 

 

주의할 점은 'React.memo'를 사용하면 컴포넌트 내부에서 'props'가 변경되어도 리렌더링되지 않기 때문에, 필요한 경우엠나 사용하는 것이 좋다. 

 

 

React.memo와 useMemo 비교

React.memo와 useMemo는 둘다 React에서 성능최적화를 위해 사용되는 도구들이지만, 서로 다른 목적과 사용방법을 갖는다.

 

useMemo

'useMemo'는 함수형 컴포넌트 내부에서 계산비용이 높은 연산은 캐시하고, 이전에 계산된 결과를 재사용할때 사용된다.

 

'useMemo' 훅은 계산결과를 캐시하고 필요할때마다 다시 계산하지않고 이전 결과를 반환하여 성능을 향상시킨다. 

 

const MyComponent = ({ data }) => {
  const expensiveCalculation = useMemo(() => {
    // 계산 비용이 높은 작업
    return /* 계산 결과 */;
  }, [data]); // data가 변경되었을 때만 재계산

  // 컴포넌트의 내용
};

 

React.memo

'React.memo'는 컴포넌트의 리렌더링을 최적화하기 위해 사용된다.

 

컴포넌트의 'props'가 변경되었을 때 이전에 렌더링된 결과를 재사용하여 불필요한 리렌더링을 방지한다. 주로 함수형 컴포넌트를 래핑하여 사용한다. 

 

const MyComponent = React.memo((props) => {
  // 컴포넌트의 내용
});

 

요약

'React.memo'는 컴포넌트의 리렌더링을 최적화하고, 

 

'useMemo'는 계산결과를 캐시하여 성능을 향상시키는데 사용된다.