최적화 React.memo (feat. useMemo & useCallback

LOCA·2023년 10월 30일
0

리액트

목록 보기
3/3
post-thumbnail

"이컴포넌트는 외자꾸 렌더링되는거지 불필요한 렌더링을 좀 줄일수 없을까 ?"
라는 의문이 들때가 있다. 굳이 반복해서 렌더링될 필요가 없는 컴포넌트가 계속해서 반복적으로 렌더링이 된다면 , 또 그 컴포넌트가 렌더링이 될때마다 복잡한 로직을 수행한다면 우리의 컴포넌트 성능은 나락으로 가버릴지도 모른다.
React.memo와 useMemo, useCallback과 함께 해결해보자.

React.memo을 배우기 전에 알아야 하는 것 - 리렌더링

  1. 함수 컴포넌트는 단지 함수다. 다시한번 강조하면 함수형 컴포넌트는 단지 JSX를 return 하는 함수이다.
  2. 컴포넌트가 렌더링 된다는 것은 그 함수(컴포넌트)를 호출하여서 실행되는 것을 의미한다.
    즉, 함수가 실행 될 때마다 내부에 선언되어 있던 표현식(변수, 또다른 함수등) 도 매번 다시 선언되어 사용된다.
  3. 컴포넌트는 자신의 state가 변경되거나, 부모에게서 받는 props가 변경되었을때마다 리렌더링 된다.
    하위컴포넌트에 최적화 설정이 되어 있지 않다면 부모에게서 받는 props가 변경되지 않았더라도 리렌더링 되는것이 기본이다(부모컴포넌트 리렌더링시 당연히 자식컴포넌트가 리렌더링).

React.memo


Student 컴포넌트는 School컴포넌트를 부모로 두고 School컴포넌트로부터 props로 이름,나이,주소를 props로 전달 받는다.
전달받는 props에 따라서 다른 학생의 정보를 보여주는 컴포넌트이다.

리액트에서는 기본적으로 부모넘포넌트가 렌더링이되면 모든 자식컴포넌트들도 자동적으로 렌더링이 된다. 그 말은 스쿨컴포넌트가 렌더링이 될때마다 student 컴포넌트 또한 렌더링이 된다는 말이다.
student 컴포넌트는 항상 같은값을 props로 전달받는 상태지만, 만약 school컴포넌트가 어떠한이유로 자주 리렌더링이 일어나는 상태라고 한다면, student컴포넌트는 늘 같은 결과를 보여줌에도 불구하고 함께 리렌더링이 된다.
만약 스튜던트가 렌더링이 될때마다 성적데이터를 새로 가져와야 한다던지, 성능의 무리가 올수있는 복잡한 로직을 반복해서 실행해야 한다고 가정했을때 계속 렌더링이 된다면 끔찍할 것이다.
우리앱의 성능이 작살이 날것이다.
이럴 때 우리는 student 컴포넌트의 렌더링 횟수를 제한 해 줄 필요가 있다.
꼭 필요할 때만 렌더링이 되도록 말이다.
여기서 우리는 이런 생각을 하게된다 .
student 컴포넌트가 받는 props가 변경이 될 때만
즉, 이름 ,나이, 주소가 변경 되는 경우에만 렌더링이 되게 된다면 훨씬더 효율적이지 않을까 ? 하는 생각 말이다.
지금 같은 경우는 props가 업데이트 되지 않는 student 컴포넌트를 굳이 렌더링 해 줄 필요가 없다. 어차피 계속 같은 결과를 화면에 보여주기 때문이다.

여기서 우리는 리액트에서 제공하는 react.memo를 사용하면된다 .
리액트 메모는 리액트에서 제공하는 고차컴포넌트(HOC) 다.

고차 컴포넌트란 어떤 컴포넌트를 인자로 받아서 새로운 컴포넌트를 반환해주는 함수이다.
React.memo라는 고차 컴포넌트에 어떤 컴포넌트를 넣어주면 ui적으로나 기능적으로는 똑같지만
좀더 최적화된 컴포넌트를 반환해 준다. 최적화가 된 컴포넌트는 렌더링이 되야할 상황에 놓일때마다 PropCheck 를 통해 자신이 받는 props에 변화가 있는지 없는지 확인을 하게된다.

이렇게 확인을 해서 props에 변화가 있다면 렌더링을 하고 props의 변화가 없다면 새로 렌더링을 하는게아니라 기존에 이미 렌더링이 된 내용을 재사용 한다.



위의 School 컴포넌트(부모) 가 렌더링이 될때마다 Student컴포넌트(자녀)도 자동적으로 렌더링이 될 상황에 놓이게된다. 이때 Student 컴포넌트가 리액트메모를 통해 최적화가 되어 있따면,
이상황에서 Studnet컴포넌트는 PropCheck를 하게 되고, name,age,address중 변화가 있다면 렌더링을 하고, 변화가 없다면 재사용을 한다.


리액트 메모의 memoMemoization을 뜻한다.
Memoization이란 이미 계산해 놓은 값을 메모리저장해 놓고 필요할 때마다 꺼내서
재사용 하는 기법 을 뜻한다.

우리가 이미 렌더링을 해놓은 Student 컴포넌트를 메모리 어딘가에 저장해 놓고 새로 렌더링 하는 대신 꺼내서 재사용 하는 것이 리액트 메모의 메모이제이션 기법이다.



리액트 메모를 잘 사용한다면 렌더링횟수 감소로 인해 이득을 많이 볼 수 있지만
무분별하게 사용한다면 오히려 성능이 독이 될수가 있다.
컴포넌트를 메모에이징 할때 렌더링된 결과를 어딘가에 저장해 놓아야 하기 때문에
메모리를 추가적을 소비하기 때문이다.


리액트 메모를 사용하기에 적합한 상황

  1. 컴포넌트가 같은 props로 자주 렌더링이 될때
  2. 컴포넌트가 렌더링이 될때마다 복잡한 로직을 처리해야 한다면

React.memo는 넘겨받은 props의 변경 여부만을 체크한다. 하지만 컴포넌트 내부에서 useState같은 훅을 사용 하고 있는 경우에는 상태가 변경 되면 리렌더링 된다.
사용법은 아주 간단하다 !!

profile
helloWorld

0개의 댓글