React - Pure Component와 memo

Noma·2021년 4월 12일
0

1. Pure Component와 memo

리엑트에서는 state나 관련된 props가 변경되면 전체가 업데이트(render)된다.

하지만 다음과 같은 문제점을 가지므로,

  1. 동일한 propsstate에도 같은 결과를 불필요하게 렌더링 한다.
    → 리엑트는 VDOM(Virtual DOM)을 써서 지금 업데이트 될 것과 이전 것을 비교해 실제로 업데이트 해야 하는 것들만 DOM 요소에 업데이트 하기 때문에 성능에 큰 영향은 없다.

  2. componenetDidMount()와 같이 Component가 마운트될 때마다 호출해주는 함수가 등록되어 있을 때, 이런 함수안에 서버에서 데이터를 받아온다든지 등의 무거운 로직들을 수행한다면 매우 비효율적으로 반복되어질 수 있다.

이를 방지하기 위해 사용되는 것이 PureComponent와 memo이다.

  • 클래스 컴포넌트에서는 Pure Component 사용
import React, { PureComponent } from 'react';
// Component를 PureComponent로 바꿔주면 된다.
class Cart extends PureComponent {
    state={
        ...
      };
    render() {
        return (
           ...
        );
    }
}
export default Cart;
  • 함수 컴포넌트에서는 memo를 사용
import React, { memo } from 'react';
// 컴포넌트를 memo로 감싸주면 된다.
const Example = memo((props) => {
  ...
  return(
      ...
  );          
});

export default Example;

(이 둘은 비슷한 특성을 가지므로 그 중 하나, Pure Component만 다루겠다.)

Pure Component는 stateprops에 변화가 없다면 render 함수가 실행되지 않는다. 이는 React.Component와 달리 shouldComponentUpdate()를 구현해 propsstate를 이용한 얕은(shallow) 비교를 구현한다는 점에서 차이가 있다.

따라서 컴포넌트에 복잡한 자료 구조가 포함되어있다면, 깊은 곳에 차이가 존재함에도 불구하고 차이가 없다고 판단하는 잘못된 결과를 만들어낼 수 있으므로,

  1. propsstate의 구조가 간단할 것으로 예상될 때에만 Pure Component를 상속하고,
  2. 깊은 자료 구조에 변화가 있다면 forceUpdate()를 사용하거나, 중첩된 데이터들을 빠르게 비교할 수 있도록 불변 객체의 사용을 검토해보자.

Pure Component의 shouldComponentUpdate()는 컴포넌트의 하위 트리에 대한 props 갱신 작업을 수행하지 않으므로, 자식 컴포넌트들이 "순수한지" 확인해야 한다.

2. Shallow Comparison

컴포넌트를 업데이트 할 때 현재 상태와 새로운 상태를 비교하는 방식에는 두가지가 있다. 그 중 Shallow Comparison을 다시 정리해보자면,

  • Pure Component인 경우 사용하는 비교 방식으로, 오브젝트의 최상위 reference를 비교해 달라진 점이 있다면 컴포넌트를 업데이트 한다.

  • Pure Component의 shouldComponentUpdate()는 컴포넌트를 업데이트 해야될 지 안해도 될 지를 물어보는 함수이다. 컴포넌트의 이전 props와 state를 얕게 비교해 그 결과에 따라 true, false를 리턴한다.

❗ 일반 Component인 경우, 따로 Lifecycle methods중 하나인 shouldComponentUpdate를 구현하지 않았다면, setState가 호출 될 때마다 render 함수가 반드시 호출된다.

3. shouldComponentUpdate()

  • 📍 예시__1
const cart1 = { name: 'lemon' };
const cart2 = cart1;

1. cart1 == cart2  // true

2. ShouldComponentUpdate // false

둘의 참조값이 같으므로, 업데이트 할 필요가 없어서 ShouldComponentUpdate함수는 false를 리턴

  • 📍 예시__2

( 이때, 동일한 값을 가지고 있더라도, 둘은 엄연히 다른 오브젝트이므로 다른 참조값을 가지게 됨 )

const cart1 = { name: 'lemon' };
const cart2 = { name: 'lemon' };

1. cart1 == cart2 // false

2. ShouldComponentUpdate // true

둘의 참조값이 다르므로, 업데이트가 필요하다. 즉ShouldComponentUpdate함수는 true를 리턴하게 된다.

📚 reference

https://reactjs.org/docs/react-api.html

profile
Frontend Web/App Engineer

0개의 댓글