문제 상황

스크린샷 2023-08-04 오후 7.34.50.png

위와 같은 페이지가 있다. page.tsx > List.tsx > Item.tsx \* n의 형태를 띄고 있다.

구조를 어떻게 짜야 렌더링을 최소화 할 수 있을까?

우선, 완료 버튼을 누르면 내가 누른 요소들의 상태를 서버에 전송해야 한다. 그렇기에 요소들의 상태를 선언은 버튼과 같은 depth에 있어야 한다. 버튼에는 setState, 각 Item에는 setStatestate를 넘겨주는 것이다.

그리고, 각 ItemReact.memo로 감싸야 한다. 왜냐하면, 한 요소의 상태가 바뀌면,그 부모 컴포넌트(List 컴포넌트)가 리렌더링이 일어나고, 그 자식들(Item 컴포넌트들) 또한 리렌더링이 일어나기 때문이다. 그런데 다른 Item은 바뀐 것이 없기 때문에 리렌더링이 일어날 필요가 없다. 즉, 불필요한 리렌더링이다.

또한, Item에 넘겨주는 함수도 신경써야 한다. setState 자체는 리렌더링이 일어나도 참조가 그대로 유지되지만, () => handler(id)처럼 렌더링할 때마다 새로 만드는 핸들러는 매번 다른 객체이기에 Item컴포넌트는 리렌더링이 일어난다. 이런 함수는 부모 컴포넌트에서 useCallback으로 감싸, 함수의 불변성을 지켜야 한다.

Untitled

메모 전.gif

메모 후.gif

각각 React.memo, useCallback으로 memoization을 하기 전과 후이다. 확연한 렌더링 차이가 있다. 작은 규모의 프로젝트에서는 크게 체감이 안될 수 있지만, 이러한 것들이 쌓이고 쌓이면 크나큰 성능차이를 불러일으킬 것이다.