본문 바로가기
Front-End/React

[ React ] React 기본 ⑦ 최적화 - 최적화 완성

by 2CHAE._.EUN 2022. 10. 22.

[ 일기 데이터 하나를 삭제할 때 나머지 아이템 전부에서 리랜더링이 발생하는 문제를 해결하기 ]

 

아이템이 여러 개 있거나, 사진이나 동영상을 랜더하게 되는 경우 메모리를 심하게 낭비하게 된다. 

 

DiayEditor는 App 컴포넌트로부터 받은 2개의 함수와,  5개의 데이터를 prop으로 받는다. 그 중

일기 아이템을 수정해서 변화할 수 있는 content를 제외한 나머지는 변화할 수 없는 데이터이다. 

그렇기 때문에 onEdit, onDelete, content 3개에 집중해서 최적화를 하면 된다. 

 

1. 최적화의 시작은 React.memo로 컴포넌트를 묶어주는 것이다.

 

React.memo : 리랜더링 되지 않았으면 하는 컴포넌트를 전달해준다면 props가 바뀌지 않는 이상 리랜더링되지

않은 강화된 새로운 컴포넌트를 돌려준다.

 

DiaryItem.js

import React,{ useRef, useState } from "react";

...

export default React.memo(DiaryItem);

 

DiaryItem는 React.memo로 감싸기만 한다고 최적화가 일어나지 않는다. 왜냐하면 prop으로 전달받는 

onEdit, onDelete는 data state가 변화하면 재생성될 수 밖에 없는 함수이기 때문이다. 그래서 App 컴포넌트에서

onCreate를 최적화했던 useCallback을 사용했던 것처럼 똑같이 해줘야 한다.

 

2. App 컴포넌트에 존재하는 onDelete, onEdit 함수에 useCallback 적용해주기

 

App.js

  const onDelete = useCallback((targetId) => {
    setData((data) => data.filter((it) => it.id !== targetId));
  }, []);

  const onEdit = useCallback((targetId, newContent) => {
    setData((data) =>
      data.map((it) =>
        it.id === targetId ? { ...it, content: newContent } : it
      )
    );
  }, []);

 

setData 함수에는 data를 다루는 부분을 전달해서 data를 리턴하는 방식으로  변경해줘야 한다.

왜냐하면 setData에 전달되는 파라미터에 최신 state가 전달되기 때문에 항상 최신 state를 이용하기 위해서는

함수형 업데이트의 인자 부분의 data를 사용해야 한다. 또한 리턴 부분의 data를 사용해야 최신형 업데이트를

사용할 수 있다.

 

지금은 일기 데이터를 새로 삭제하거나 추가해도 DiaryItem은 리랜더링이 발생하지 않고 방금 작업한

아이템에 대해서만 리랜더링이 발생하게 된다.