ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [컴포넌트 최적화] React.memo, useMemo, useCallback의 차이점과 활용
    프론트엔드 개발자가 될거야./react 2022. 9. 26. 16:46

     

    세 달 동안 React기반으로 세 개의 프로젝트를 완성했다.

    구현하는 것을 목적으로 달려왔기에

    프로젝트가 끝난 이후 리팩토링을 진행하면서 나의 코드가 효율적인지 아닌지 고민해 보게 됐다.

    그러면서 리액트의 렌더링에 대해 더 깊게 알고 싶었다.

     

    리액트는 매우 유용하지만 렌더링에 주의하여 사용해야 한다.
    렌더링을 할 필요가 없는 컴포넌트까지 항상 렌더링이 된다면 이는 성능이 좋지 않다고 할 수 있다.

    이를 위해 활용해야 하는 것이 바로 React.memo, useMemo, useCallback이다.

     

    먼저 알아야 하는 것은 리액트에서 리렌더링이 발생하는 3가지 조건이다.

    리액트에서 리렌더링이 발생하는 3가지 조건

    1. 본인이 가진 state에 변화가 생긴 경우
    2. 부모 컴포넌트가 리렌더링이 일어난 경우
    3. 자신이 받은 props가 변경되는 경우

    이렇게 세 가지가 있다. 

     


    1. React.memo

    React.memo는 고차 컴포넌트이다.

     

    - 고차 컴포넌트란

    : 컴포넌트 로직을 재사용하기 위한 React의 고급 기술이다.

    : 함수의 매개변수로 컴포넌트를 전달하면 더 좋아진 컴포넌트를 반환해주는 친구다.

    즉, React.memo는

     

    부모에게 받은 prop가 바뀌지 않으면 리렌더링 하지 않는 강화된 컴포넌트로 만들어준다.

     

    이에 React.memo는 부모 컴포넌트가 리렌더링되면 상관없는 자식 컴포넌트까지 재렌더링이 될 때 사용하면 된다.

    그렇게 React.memo는 넘겨받은 props의 변경 여부를 체크하고 변경되지 않았으면 렌더링이 되지 않게 해준다.

     

    - 주의할 점

    React.memo는 얕은 복사를 하므로 props가 객체일 때는 같은 값을 참조하고 있는지 비교해야 한다.

    이를 위해서는 

    function MyComponent(props) {
      /* 컴포넌트 로직 */
    }
    function areEqual(prevProps, nextProps) {
      /*
      전달되는 nextProps가 prevProps와 같다면 true를 반환, 같지 않다면 false를 반환해 준다.
      */
    }
    
    export default React.memo(MyComponent, areEqual);

    이렇게 React.memo의 두번째 인자로 넣어주면 된다.

     

    - 사용법

    export default React.memo(MainSectionVideo);

    2. useMemo

    React.memo와 비슷하겠거니 했는데 아니다 전혀 다르다. 그러니 절대 혼동하지 말자.

     

    useMemo는 함수의 연산을 최적화한다.

    함수가 어떤 값을 리턴하고 있는데 그 리턴까지의 연산을 최적화하고 싶다면

    useMemo를 사용해서 어떤 값이 변할 때만 이 연산을 하고 싶은지 말해줄 수 있다.

     

    즉,

    특정 상황에서는 동작되어야 하는 함수가
    컴포넌트의 렌더링 조건에 따라 지속적으로 실행되는 경우 사용할 수 있다.

     

    - 사용법

    const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

    인자로 함수와 디펜던시를 넘겨받는다.

    두번째 인자로 넘겨준 의존 인자 중 하나라도 값이 변경되면 첫번째 인자인 함수를 재실행한다.

    이는 매 렌더링 할 때마다 소요되는 불필요한 계산을 피할 수 있다.

     

    - useEffect랑 뭐가 다를까?

    디펜던시때문에 useEffect와 뭐가 다른지 헷갈릴 수도 있다.

    useEffect는 html 보여주는 게 끝나면 그때 실행이 되고

    useMemo는 처음부터 같이 실행이 된다.

    즉, 실행 시점의 차이가 있다!

     


    3. useCallback

    컴포넌트가 렌더링 될 때만 내부적으로 사용된 함수가 새롭게 생성되는 경우,

    자식 컴포넌트에 prop으로 새로 생성된 함수가 넘겨지게 되면 불필요한 리렌더링이 일어날 수 있다.

     

    자식 컴포넌트에 함수를 props으로 줄 때는 useCallback을 사용하여 리렌더링이 안되도록 하자.

     

    이 또한

    이렇게 디펜던시를 줄 수 있는데

    두 번째 인자로 전달한 디펜던시의 값이 변하지 않으면

    첫 번째 인자로 전달한 콜백 함수를 계속 재사용할 수 있도록 도와준다.

     


    최종 정리

    React.memo, useMemo, useCallback은 모두 불필요한 렌더링 또는 연산을 제어하는 용도로 성능 최적화에 그 목적이 있다.

     

    그러나

    React.memo는 컴포넌트 자체의 렌더링을 최적화하고 싶을 때 컴포넌트를 감싸주는 고차 컴포넌트이고

    useMemo는 함수의 연산량이 많을 때 이전 결과값을 재사용하는 목적이고

    useCallback은 함수가 재생성되는 것을 방지하기 위한 목적이다.

     


    참고한 블로그 : )

    https://velog.io/@sunkim/React.memo-useMemo-useCallback-역할-및-차이점

    https://iborymagic.tistory.com/115

    댓글

Designed by Tistory.