useMemo && 컴포넌트 랜더링 최적화

Jean Young Park·2022년 10월 18일
0

react

목록 보기
9/32

React.memo

React.memo는 함수형 컴포넌트를 감싸서 해당 컴포넌트의 props가 변경되었을 때만 리랜더링을 수행하도록 지정할 수 있는 React 훅이다. 이를 사용하면, 컴포넌트가 불필요하게 리랜더링되는 것을 방지 할 수 있다.

불필요하게 랜더링되는 예시

import React, { useState } from 'react';

const Counter = ({ count }) => {
  return <div>{count}</div>;
};

const App = () => {
  const [count, setCount] = useState(0);
  const [text, setText] = useState('');

  const handleTextChange = (e) => {
    setText(e.target.value);
  };

  return (
    <div>
      <Counter count={count} />
      <input type="text" value={text} onChange={handleTextChange} />
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
};

위 코드는 Counter 컴포넌트와 App 컴포넌트를 정의하고 있다. Counter 컴포넌트는 count라는 props를 전달받아서 해당 값이 출력되는 컴포넌트이다. App 컴포넌트는 count와 text라는 두 개의 상태를 관리하고 있다.
Counter 컴포넌트는 count라는 props만을 사용하는데, App 컴포넌트의 text 상태가 변경될 때마다 Counter 컴포넌트도 리랜더링이 수행된다. 이를 해결하기 위해 React.memo를 사용할 수 있고 파일을 분리하면 자동으로 최적화가 수행된다.

React.memo는 클래스형 컴포넌트에서 사용되는 shouldComponenetUpdate 메서드를 대신하여 사용할 수 있다.
React.memo는 컴포넌트를 감싸는 형태로 사용된다. 아래는 예시이다.

import React, { memo } from 'react';

const MyComponent = ({ prop1, prop2 }) => {
  // ...
};

export default memo(MyComponent);

React.memo는 두 개의 매개변수를 받는다. 첫 번째 매개변수는 컴포넌트 자체를 나타내는 함수이며, 두 번째 매개변수는 클래스형 컴포넌트에서 사용되는 propsAreEqual함수이다. propsAreEqual 함수는 이전 props와 새로운 props를 비교하여 동일하면 true, 다르면 false를 반환한다. 두 번째 매개변수를 생략하면, 기본적으로 얕은 비교를 수행하게 된다.

얕은 비교란?
타입 데이터의 경우 값이 동일한지만 비교하고, 객체나 배열의 경우, 참조 값이 같은지를 비교하는 것을 의미한다. 예를 들어, 배열이나 객체를 비교할 때는 내부의 값이 같아도 참조하는 메모리 주소가 다르면 다른 것으로 판단된다. 따라서, 컴포넌트의 props나 state가 변경될 때, 객체나 배열의 경우 깊은 비교를 하지 않고 얕은 비교를 하기 때문에, 객체나 배열이 바뀌어도 리렌더링이 발생하지 않을 수 있다.

const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2 };

console.log(obj1 === obj2); // false

깊은 비교란?
객체나 배열의 경우에도 모든 값들이 같은지를 비교하는 것을 의미한다.

const obj1 = { a: 1, b: 2 };
const obj2 = { a: 1, b: 2 };

console.log(JSON.stringify(obj1) === JSON.stringify(obj2)); // true

그러나 React.memo를 사용하면서도 주의해야 할 점이 있다. React.memo는 props 비교를 수행하여 리랜더링을 결정하기 때문에, 객체나 배열과 같은 참조타입(props로 전달되는 값)을 변경하면 예상치 못한 리랜더링이 발생할 수 있다.(또한 권장되지 않는다.) 이러한 문제를 해결하기 위해서는 객체나 배열을 불변 객체로 관리하거나, React.useCallback 등의 다른 최적화 기법을 활용해야한다.

0개의 댓글