React.memo 사용

# 정의



반응.메모


  • 구성 요소가 주어진 동일한 결과를 렌더링하는 경우 일부 성능 향상을 위해 사용할 수 있는 상위 구성 요소props
  • 소품 변경 사항을 확인하고 구성 요소 렌더링을 건너뛰고 이전 및 현재props가 동일한 경우 마지막으로 렌더링된 결과를 재사용합니다.

  • 
    function PizzaComponent({ name, price }) {
      /* render using props */
      return (
        <div>Pizza: {name}</div>
        <div>Total: ${price}</div>
      )
    }
    
    export default React.memo(PizzaComponent);
    
    


    이 구성 요소는 🍕 이미지가 주어지면 메모이제이션 후보이며 항상 동일한 🍕 세부 정보를 렌더링합니다.
  • 기본적으로 props의 얕은 비교를 수행합니다.
  • props 비교에 대한 사용자 정의 컨트롤의 경우 사용자 정의 비교 함수를 두 번째 인수로 제공할 수 있습니다.

  • 🍕에 사용할 수 있는 다양한 토핑도 표시하도록 PizzaComponent를 확장해 보겠습니다. 토핑은 문자열의 배열입니다. 위에서 언급했듯이 React.memoprops 의 얕은 비교를 수행하므로 이 경우 toppings 배열이 동일하게 유지되더라도 여전히 다시 렌더링됩니다.

    그렇다면 이 문제를 어떻게 해결할 수 있을까요?

    다음과 같이 사용자 지정 비교 함수를 전달합니다.

    
    function PizzaComponent({ name, price, toppings }) {
      function areEqual(prevProps, nextProps) {
        /*
        return true if passing nextProps to render would return
        the same result as passing prevProps to render,
        otherwise return false
        */
        return (
          prevProps.name === nextProps.name,
          prevProps.price === nextProps.price,
          prevProps.toppings.every(topping => nextProps.toppings.includes(topping))
        )
      }
    
      /* render using props */
      return (
        <div>Pizza: {name}</div>
        <div>Total: ${price}</div>
        {toppings.map((topping, index) => (
          <div key={`${name}_${topping}`}>{topping}</div>
        ))}
      )
    }
    
    export default React.memo(PizzaComponent, areEqual);
    
    


    # 리액트 메모 사용하기



    다음과 같은 경우 성능 향상을 위해 React.memo를 사용하십시오.
  • 구성 요소가 자주 다시 렌더링됨
  • 구성 요소는 일반적으로 다시 렌더링하는 동안 동일한props 제공됩니다
  • .
  • 구성 요소에 추론props 동등성 검사
  • 에 대한 관련 요소가 포함되어 있습니다.

    If a component with hooks is wrapped with React.memo, then it will still re-render when state or context changes.



    # 기능을 소품으로 사용하여 반응 메모



    다음과 같이 PizzaComponent라는 onOrder에서 🍕를 주문하는 기능을 추가해 보겠습니다.

    
    function PizzaComponent({ name, price, toppings, onOrder }) {
      function areEqual(prevProps, nextProps) {
        /*
        return true if passing nextProps to render would return
        the same result as passing prevProps to render,
        otherwise return false
        */
        return (
          prevProps.name === nextProps.name,
          prevProps.price === nextProps.price,
          prevProps.toppings.every(topping => nextProps.toppings.includes(topping))
        )
      }
    
      /* render using props */
      return (
        <div>Pizza: {name}</div>
        <div>Total: ${price}</div>
        {toppings.map((topping, index) => (
          <div key={`${name}_${topping}`}>{topping}</div>
        ))}
        <button onClick={onOrder}>Order</button>
      )
    }
    
    export default React.memo(PizzaComponent, areEqual);
    
    


    다음과 같이 사용합시다.

    
    function App ({ store }) {
      const { pizza } = store;
      return (
        <PizzaComponent
          name={pizza.name}
          price={pizza.price}
          toppings={pizza.toppings}
          onOrder={() => placeOrder(pizza.price, pizza.coupon)}
        />
      )
    }
    
    

    React.memo는 얕은 비교를 수행하므로 매번 콜백 함수onOrder를 새 함수prop로 볼 때마다 다시 렌더링합니다.

    이 문제를 해결하기 위해 다음과 같이 onOrder로 전달된 함수를 useCallback로 래핑할 수 있습니다.

    
    function App ({ store }) {
      const { pizza } = store;
      /**
       * This will always return the same function instance as long as pizza is the same.
       */
      const onOrder = useCallback(
        () => placeOrder(pizza.price, pizza.coupon),
        [pizza],
      );
    
      return (
        <PizzaComponent
          name={pizza.name}
          price={pizza.price}
          toppings={pizza.toppings}
          onOrder={onOrder}
        />
      )
    }
    
    

    좋은 웹페이지 즐겨찾기