반응형

🚀 React.memo

리액트에서 부모 컴포넌트가 렌더링 될 때 해당 컴포넌트에 속하는 모든 자식 컴포넌트 또한 렌더링 됩니다. 하지만 부모 컴포넌트에서 자식 컴포넌트로 내려주는 props가 바뀌지 않았다면, 해당 자식 컴포넌트를 리 렌더링 하지 않아도 될 것입니다. 컴포넌트에서 리 렌더링이 필요한 상황에서만 해주도록 설정을 할 수 있는데 이때 사용하는 함수가 바로 React.memo 함수입니다.

 

React.memo 사용법

const MyComponent = React.memo(function MyComponent(props) {
  /* props를 사용하여 렌더링 */
});

또는

function MyComponent(props) {
  /* props를 사용하여 렌더링 */
}
function areEqual(prevProps, nextProps) {
  /*
  nextProp가 prevProps와 동일한 값을 가지면 true를 반환하고, 그렇지 않다면 false를 반환
  */
}
export default React.memo(MyComponent, areEqual);

React.memo는 props가 변경됐는지 아닌지를 체크하여 같은 props가 들어온다면 리액트는 컴포넌트 렌더링 과정을 스킵하고 마지막에 렌더링 된 결과를 재사용합니다.

 

React.memo 예제

React.memo를 사용하여 props가 변경되지 않은 컴포넌트들은 렌더링 되지 않도록 침실, 주방, 욕실의 불을 켜고 끄는 예제를 통해 한번 살펴보겠습니다.

// App.js

import React, { useState } from "react";
import SmartHome from "./components/SmartHome";

const App = () => {
  return (
    <div style={{ position: "absolute", top: "50%", left: "50%" }}>
      <SmartHome />
    </div>
  );
};

export default App;
// ./components/Light.jsx

import React from "react";

function Light({ on }) {
  console.log({ on });
  return <div>{on ? "💡" : "⬛"}</div>;
}

export default Light;
// ./components/SmartHome.jsx

import React, { useState, useCallback } from "react";
import Light from "./Light";

function SmartHome() {
  const [masterOn, setMasterOn] = useState(false);
  const [kitchenOn, setKitchenOn] = useState(false);
  const [bathOn, setBathOn] = useState(false);

  const toggleMaster = () => {
    setMasterOn(!masterOn);
  };
  const toggleKitchen = () => {
    setKitchenOn(!kitchenOn);
  };
  const toggleBath = () => {
    setBathOn(!bathOn);
  };

  return (
    <div>
      <button onClick={toggleMaster}>
        침실
        <Light on={masterOn}></Light>
      </button>
      <button onClick={toggleKitchen}>
        주방
        <Light on={kitchenOn}></Light>
      </button>
      <button onClick={toggleBath}>
        욕조
        <Light on={bathOn}></Light>
      </button>
    </div>
  );
}

export default SmartHome;

자식 컴포넌트인 Light 컴포넌트에 대해 침실과 욕조는 props가 변경되지 않았음에도 불구하고 렌더링 된 것을 확인하였습니다. 같은 props에 대한 리 렌더링을 방지하기 위해 Light컴포넌트에 React.memo를 적용해줍시다!

// ./components/Light.jsx

import React from "react";

function Light({ room, on }) {
  console.log({ room, on });
  return <div>{on ? "💡" : "⬛"}</div>;
}

export default React.memo(Light);

침실 버튼 클릭 시 침실에 대한 컴포넌트만 렌더링 되었습니다.

 

 

언제 React.memo()를 써야 할까

컴포넌트가 같은 props로 자주 렌더링 되거나, 무겁고 비용이 큰 연산이 있는 경우!

언제 React.memo()를 사용하지 말아야 할까

컴포넌트가 무겁지 않고 자주 다른 props로 렌더링 되는 경우!

 

useMemo와 React.memo의 차이점...?

  1. React.memo는 리액트의 HOC(Higher Order Component) 패턴, useMemo는 리액트 Hooks의 함수
  2. React.memo는 HOC이기 때문에 클래스형, 함수형 컴포넌트 모두 사용 가능
    But, useMemo는 Hook이기 때문에 함수형 컴포넌트에서만 사용 가능

 

 

반응형

+ Recent posts