만족

[React] React.memo를 이용한 함수 컴포넌트 최적화 본문

[React] React.memo를 이용한 함수 컴포넌트 최적화

FrontEnd/React Satisfaction 2020. 7. 6. 00:24

https://ko.reactjs.org/docs/react-api.html#reactmemo

 

React 최상위 API – React

A JavaScript library for building user interfaces

ko.reactjs.org

 

요즘 클래스형 컴포넌트를 갖다 버리고, 거의 함수 컴포넌트만 사용중이다.

 

클래스형 컴포넌트에서는 shouldComponentUpdate 메서드를 사용하여 해당 컴포넌트를 업데이트할지 말지 결정할 수 있었으나,

함수 컴포넌트에서는 할 줄 몰라서 그냥 내버려뒀다.

(사실 페이지 내에 요소가 그렇게 많지가 않아서 크게 신경쓰지 않아도 문제는 없었다)

 

그러나, 엘리먼트가 매우 많은 페이지를 만들면서 해당 문제를 해결하는 방법에 대해 알아보았다.

 

탭바 컴포넌트 구조를 대충 도식화 해보면

이런 식으로 되어있다. 

(탭바 바디 내의 게임 로그는 각각 최대 200, 100, 100개가 들어있다)

 

탭바 컴포넌트가 전체 내용을 감싸고 있으며, 탭바 헤더에서 어떤 탭을 누르면 그 탭에 해당하는 바디를 골라 visible상태로 만들고

나머지는 전부 숨겨버린다.

 

문제는 여기서 발생한다.

 

리액트에서는 기본적으로 상위 컴포넌트가 업데이트되면

그 컴포넌트를 포함하여 하위의 컴포넌트까지 리렌더링된다.

 

따라서 탭을 고르게 되면, 최대 400개의 게임 로그 컴포넌트가 리렌더링 되어 엄청난 렉을 유발한다.

 

또한 실제로는 게임 로그 컴포넌트 내에 또 하위 컴포넌트가 존재하므로 리렌더링 횟수는 기하급수적으로 늘어난다.

 

 

이제 게임 로그에 React.memo를 사용해서 필요한 경우에만 선택적 리렌더링을 할 수 있다.

 

React.memo의 첫 번째 매개변수에는 타겟 컴포넌트가 들어간다.

나의 경우에는 GameLog가 된다.

 

두 번째 매개변수에는 함수를 넣어주거나, 아무것도 전달하지 않으면 된다.

 

전달하지 않으면(null), 해당 컴포넌트는 props의 변화로는 업데이트되지 않는다.

(클래스 컴포넌트에서 shouldComponentUpdate의 바로 아래에 return false를 입력한것과 비슷하다고 보면 된다.)

 

함수를 전달할 경우, 해당 함수에는 이전 Props와 다음 Props가 전달되고 해당 값을 비교하여 리렌더링이 필요한지 아닌지를 나타내주면 된다.

따라서, prop의 원하는 값을 비교하여, 업데이트가 필요한 값을 비교해주면 된다.

(해당 함수가 true를 리턴하면 리렌더링하지 않고, false를 리턴하면 리렌더링한다)

 

export default React.memo(YourComponent, (prev, next)=>{
  return false //리렌더링 함
  return true //리렌더링 안함
  return prev.value === next.value //props.value의 값이 바뀌었을 때만 리렌더링함
});

 

이런식으로 사용해주면 선택적 리렌더링이 가능해져 성능에서 큰 이득을 볼 수 있게 된다.

 

React.memo에서 말하는 리렌더링이란, 모든 종류의 리렌더링을 말하는 것은 아니다.

 

props(상위 컴포넌트에서 전달되는 값)이 변경되었을때의 업데이트 여부만을 다루는 것이고,

컴포넌트 스스로의 state가 바뀔 때는 React.memo의 조건과 관계없이 업데이트된다.

(shouldComponentUpdate와 이 점에서 다르다)

 

수정전
수정후

리렌더링만 막았을 뿐인데도 딜레이 없이 즉각적으로 탭이 전환된다 

 

 

 


Comments