[React] React.memo는 정확히 언제 왜 쓸까? (feat. PureComponent, ShouldComponentUpdate)

    728x90
    반응형
    반응형

     

    리액트를 사용하게되면서

    랜더링 최적화 / 성능 최적화에 대한 이야기를 꽤 들어왔었다.

    그러다보니 그럴때 사용하는 usecallback, usememo, react.memo 가 있고 어떻게 사용하는 지도 알고는 있었다.

    그런데 리액트 강의를 들으면서 react.memo에 관해 좀 더 구체적으로 알게 되었는데

    아 이럴때 사용하는구나 라고 구체적으로 알게 되었다.

    아무래도 내용을 겉으로만 알고 있던것 같았다...ㅠ

    그 내용을 블로그에 남기려고 한다.

     

     

    1. Class Component 에서 랜더링 최적화

    ShouldComponentUpdate

    • 정의: shouldComponentUpdate는 클래스 컴포넌트에서 사용되는 생명주기 메서드입니다.
    • 기능: 이 메서드는 컴포넌트가 업데이트되기 전에 호출되며, true 또는 false를 반환합니다. true를 반환하면 컴포넌트는 업데이트(렌더링)를 진행하고, false를 반환하면 업데이트 과정이 중단됩니다.
    • 사용 예: 컴포넌트의 props 또는 state가 변경될 때, 특정 변경만 렌더링을 트리거하고자 할 때 사용합니다.
    • 이 생명주기의 메서드의 장점이자 단점은 직접 필요한만큼 설정해주어야 한다는 것입니다.
    • 이런 귀찮음을 피하기 위한다면 purecomponent를 사용하면 됩니다.

     

    PureComponent

    • 정의: PureComponent는 Component를 확장한 서브클래스로, shouldComponentUpdate가 자동으로 구현되어 있는 클래스 컴포넌트입니다.
    • 기능: PureComponent는 props와 state의 얕은 비교를 통해 컴포넌트가 렌더링을 해야 할지 결정합니다. 얕은 비교는 현재와 변경된 props/state가 표면적으로 동일한지 확인합니다.
    • 사용 예: 데이터 구조가 간단하고 깊은 중첩이 없을 때 유용합니다. 이를 통해 성능을 자동으로 최적화할 수 있습니다.
    • 위 내용처럼 복잡한 구조의 데이터는 잘 인식하지 못하는 경우가 있어서
    • 경우에 따라 purecomponent / component + shouldComponentUpdate 를 사용하면 됩니다.

     

     

    2. Function Component에서 랜더링 최적화 (특히 props / 부모컴포넌트 관련)

    React.memo

    • 정의: React.memo는 함수 컴포넌트의 리렌더링 성능을 향상시키기 위해 사용됩니다.
    • 기능: 이 고차 컴포넌트는 props의 변화를 검사하여, 이전 렌더링 결과를 재사용할지 결정합니다. 기본적으로는 얕은 비교를 수행합니다.
    • 사용 예: 렌더링 결과가 변경된 props에만 의존하는 경우에 유용합니다. 커스텀 비교 함수를 제공하여 어떤 props 변경이 컴포넌트의 렌더링을 트리거할지 세밀하게 제어할 수도 있습니다.

    react.memo를 사용하는 방법을 좀 더 쉽게 구분해서 보자면

    컴포넌트리 리랜더링하는 경우는 3가지가 있습니다.

    1. 상태(state) 변경: 컴포넌트 내부에서 setState 호출에 의해 상태가 변경될 때.
    2. 속성(props) 변경: 컴포넌트로 전달된 props가 변경될 때.
    3. 부모 컴포넌트의 리렌더링: 부모 컴포넌트가 리렌더링 되면, 자식 컴포넌트도 기본적으로 리렌더링 됩니다. (state, props는 변하지 않았을 때)

    위 정의/사용 예에서 변경된 props에만 의존한다는 뜻은,

    결국 부모 컴포넌트가 리랜더링 되었을 때 기존에는 props가 바뀌던/안바뀌던 같이 리랜더링 되었었는데,

    props가 바뀌지 않았을때 부모컴포넌트리 리랜더링할때에는 컴포넌트를 memorize해서

    불필요한 리랜더링을 막아 준다는 것입니다.

    랜더링 최적화! 성능 최적화!

    아래 내용 좀 더 상세하게!

     

    React.memo와 리렌더링 최적화

    React.memo는 주로 props 변경에 따른 리렌더링을 최적화하기 위해 사용됩니다.

    이 고차 컴포넌트는 자신에게 전달된 props가 변경되지 않으면 리렌더링을 수행하지 않습니다.

    즉, React.memo로 감싸진 컴포넌트는 props가 같다면 부모 컴포넌트가 리렌더링 되더라도 리렌더링되지 않습니다.

    const MyComponent = React.memo(function MyComponent(props) {
      // render your component
    });
    
    // 부모 컴포넌트에서
    return <MyComponent someProp={value} />;

    위의 예시에서, MyComponent는 someProp 값에 변화가 없다면 부모 컴포넌트가 리렌더링 되어도 리렌더링되지 않습니다.

    주의할 점

    • React.memo는 오직 props의 변경만을 감지하여 결정합니다. 만약 내부 상태 또는 컨텍스트의 변화가 리렌더링의 이유라면 React.memo는 그 변화를 감지하지 못합니다.
    • 또한, React.memo는 얕은 비교를 수행합니다.
    • 따라서 객체나 배열과 같은 복잡한 구조의 props는 내용이 같더라도 참조가 다를 경우에는 재렌더링이 발생할 수 있습니다.
    • 이러한 경우, 커스텀 비교 함수를 React.memo에 제공하여 더 깊은 비교를 수행할 수 있습니다.

     

    결론

    React.memo는 주로 부모 컴포넌트의 리렌더링이 자식 컴포넌트에 불필요한 리렌더링을 일으킬 때,

    그 자식 컴포넌트의 props가 변경되지 않았다면 리렌더링을 방지하여 성능을 최적화하는 데 사용됩니다.

    따라서, 귀하가 언급한 "부모 컴포넌트의 리렌더링에만 리렌더링되지 않게 한다"는 말은

    props가 변경되지 않을 경우에 한해서 정확합니다.

     

     

     

     

     

     

    용어 설명

    React.memo가 고차함수?

    React에서 React.memo를 고차 컴포넌트(Higher-Order Component, HOC)로 분류하는 이유는,

    그것이 컴포넌트를 인자로 받고, 새로운 컴포넌트를 반환하기 때문입니다.

    고차 컴포넌트는 컴포넌트 로직을 재사용하기 위한 고급 기술로, 기존 컴포넌트를 취해 새로운 기능이 추가된 새 컴포넌트를 반환합니다.

     

     

    정의와 작동 원리

    • 고차 컴포넌트(HOC): 컴포넌트를 입력으로 받아 새로운 컴포넌트를 반환하는 함수입니다. HOC는 React의 컴포지션 모델을 활용하여 컴포넌트 간에 코드를 재사용하고, 상태 추상화와 prop 조작을 수행할 수 있도록 도와줍니다.
    • React.memo: 함수 컴포넌트의 불필요한 렌더링을 방지하기 위해 사용되며, 컴포넌트의 props가 변경되지 않았다면 React가 컴포넌트의 출력을 메모이징(기억)하고 재사용합니다. 이는 성능 최적화를 도모합니다.
    const MyComponent = ({ text }) => {
      return <div>{text}</div>;
    };
    
    const MemoizedMyComponent = React.memo(MyComponent);

    위 예시에서 React.memo는 MyComponent를 인자로 받고, MemoizedMyComponent를 반환합니다.

    이렇게 반환된 새 컴포넌트는 입력 컴포넌트와 동일한 UI를 렌더링하지만,

    props 변경에만 반응하여 불필요한 렌더링을 줄여 성능을 개선합니다.

     

     

    고차 컴포넌트의 일반적인 사용 사례

    고차 컴포넌트는 여러 가지 상황에서 유용하게 사용됩니다:

    • Prop 조작: 컴포넌트에 주입되는 props를 수정하거나 추가할 수 있습니다.
    • 상태 추상화 및 재사용: 컴포넌트 간에 공유되는 상태 로직을 HOC에서 관리할 수 있습니다.
    • 조건부 렌더링: 특정 조건에 따라 다른 컴포넌트를 렌더링하도록 할 수 있습니다.

     

     

     

     

    이렇게 react.memo에 대해서 알아보았다.

    이 함수 하나만 가지고도 이렇게 많은 내용이 나오다니..

    그래도 전 보단 확실히 잘 사용할 수 있을 것 같은 생각이 든다.

    담은엔 다른 랜더링 최적화에 사용하는 함수들도 알아보려 한다.

    중고신입들 화이팅!

    728x90
    반응형

    댓글