Musta React

[✍🏼 1/4 (Sat)] React.memo() 복습

taytay 2025. 1. 4. 15:06

좋은 질문이야! React.memo()는 컴포넌트를 메모이제이션하는 데 사용되며, 특정 상황에서 성능 최적화에 유용해. 그런데, 특히 Product처럼 Prop을 필요한 값만 쪼개서 전달하는 컴포넌트에서 굳이 메모이제이션을 추가로 사용해야 하는 이유를 이해하려면 몇 가지를 고려해야 해.

 

 

React.memo()의 동작 원리

  • React.memo()는 고차 컴포넌트(Higher Order Component, HOC)로, 같은 Prop이 전달될 때 이전 렌더링 결과를 재사용해 불필요한 리렌더링을 방지해.
  • 내부적으로는 **얕은 비교(shallow comparison)**를 통해 이전 Prop과 새로운 Prop을 비교해서 렌더링 여부를 결정해.

 

React.memo()가 유용한 이유

1. 불필요한 리렌더링 방지
부모 컴포넌트가 리렌더링될 때, 자식 컴포넌트도 기본적으로 리렌더링된다. 하지만 Product 컴포넌트처럼 Prop이 변경되지 않는 경우라면, React.memo()를 사용하면 이전 결과를 재사용해 불필요한 계산과 DOM 업데이트를 막아준다.

function Parent({ products }) {
  return (
    <>
      {products.map(product => (
        <Product key={product.id} {...product} />
      ))}
    </>
  );
}

위 경우, Parent가 리렌더링될 때 Product도 기본적으로 리렌더링된다. 하지만 React.memo()를 사용하면 Prop이 바뀌지 않는 한 Product는 리렌더링되지 않아 성능이 향상된다.

 

 

2. Prop에 의존하는 복잡한 로직 존재 시
컴포넌트 내부에 복잡한 연산이나 상태를 가공하는 로직이 있다면, React.memo()로 불필요한 재계산을 방지할 수 있다.

const Product = memo(function Product({ name, price }) {
  console.log("복잡한 로직 실행"); // Prop 변경 없으면 실행 안 됨
  return <p>{name}: {price}</p>;
});

 

 

3. 컴포넌트가 재귀적으로 렌더링 트리를 구성할 때
트리 구조에서 자식 컴포넌트의 렌더링 비용이 커질 경우, 메모이제이션으로 성능 향상 가능

 

 

언제 React.memo()를 사용하지 않아도 되는가?

1. Prop 변경이 빈번하거나, Prop이 항상 새로 생성되는 경우

  • 예를 들어, 아래와 같이 객체를 Prop으로 넘기면 React.memo()는 얕은 비교를 수행하지만, 항상 객체가 새로 생성되므로 비효율적일 수 있다.
  • 해결 방법: 객체가 아닌 개별 값으로 Prop을 전달하거나, 부모에서 useMemo()로 객체를 메모이제이션.
<Product details={{ name: "Item", price: 100 }} />

 

 

2. 컴포넌트가 매우 가볍고, 렌더링 비용이 크지 않은 경우

  • React.memo()를 사용하면 Prop 비교를 위해 추가적인 연산 비용이 발생하므로, 간단한 컴포넌트에서는 오히려 성능이 떨어질 수도 있다.

 

3. 상위 라이브러리가 이미 최적화를 제공하는 경우

  • React Query, Redux 등의 라이브러리를 사용하는 경우, 이 라이브러리들이 상태를 관리하고 불필요한 리렌더링을 방지하기 때문에 추가적인 최적화가 필요하지 않을 수 있다.

 

React.memo()가 Product 컴포넌트에 적합한 이유

  • Product는 Prop으로 데이터를 분리해 받고, 개별 Prop이 변경될 가능성이 적으므로 메모이제이션의 효율이 높아.
  • Prop에 따라 복잡한 로직이 수행될 가능성이 있으므로, React.memo()로 이를 방지하면 성능 최적화에 도움이 된다.
  • 부모 컴포넌트가 자주 리렌더링될 때, 자식 컴포넌트가 불필요하게 렌더링되지 않도록 보호할 수 있다.

 

요약

React.memo()는 컴포넌트가 Prop에 따라 불필요하게 리렌더링되는 것을 방지하는 데 유용하며, 다음과 같은 경우 특히 적합해:

  1. Prop이 변하지 않거나, 변경 빈도가 적은 경우.
  2. 컴포넌트 내부에 복잡한 연산이 있거나, 렌더링 비용이 높은 경우.
  3. 부모 컴포넌트가 자주 리렌더링되는 구조에서 자식 컴포넌트를 보호하고 싶을 때.

권장 사항:
React.memo()를 사용하는 것이 성능에 실질적인 이점을 줄 수 있는 경우라면 사용하는 것이 좋지만, 모든 컴포넌트에 무조건 적용할 필요는 없어. 성능 병목이 확인되었을 때 적용하는 것이 가장 효과적이야! 😊