useCallback , React.memo 리렌더링 개선

lim1313·2022년 1월 24일
0

테스트 동작

성별 여성 선택 => 적용하기 버튼 클릭 => 성별 남성 선택 => 적용하기 버튼 클릭 => 성별 모두 선택 => 적용하기 버튼 클릭


🍊 개선 전

CardFilter 컴포넌트에서 12번의 리렌더링이 발생하였다.


useCallback, React.memo를 통한 개선

문제

지도페이지를 구성하는 MapPage 컴포넌트에는 CardFilter, SideBar, KakaoMap 이라는 하위 컴포넌트를 가진다.
CardFilter 컴포넌트는 날짜, 성별을 표시하는 컴포넌트이며, filterSubmit이라는 함수를 상위 컴포넌트에서 props로 전달받는다.

여기서 문제는

  • 날짜, 성별을 클릭한 후 적용하기버튼을 클릭할 때마다 MapPage의 filterInfo state가 업데이트됙,
  • 이로 인한 리렌더링이 발생하여 filterSubmit 함수가 불필요하게 재생성되고
  • CardFilter 컴포넌트도 불필요하게 리렌더링된다는 것이다.

때문에, useCallback, React.memo를 통해 리렌더링을 개선하고자 하였다.

useCallback

useCallback으로 함수를 감싸게 되면 메모이제이션되고, 의존성 배열의 값이 변경될 때에만, 해당 함수를 재생성한다.

(매개변수는 전달받는 값으로 반영된다.)

개선 전 MapPage.jsx

 const filterSubmit = (...args) => {
    let [gen, start, end] = args;
    let { gender, startDate, endDate } = filterInfo;
    if (gen !== gender || start !== startDate || end !== endDate) {
      let cardFilter = { gender: gen, startDate: start, endDate: end };
      setFilterInfo(cardFilter);
    }
  };
...
   <CardFilter filterSubmit={filterSubmit} />
...

개선 후 MapPage.jsx
불필요한 로직을 제거하고 useCallback을 추가

  const filterSubmit = useCallback((...args) => {
    let [gen, start, end] = args;
    let cardFilter = { gender: gen, startDate: start, endDate: end };
    setFilterInfo(cardFilter);
  }, []);
...
   <CardFilter filterSubmit={filterSubmit} />
...

React.memo

React.memo는 컴포넌트를 메모이제이션하고, 얕은 비교를 통해 props가 변경되었을 경우 리랜더링된다.

위의 MapPage.jsx에서 useCallback으로 함수를 메모이제이션하였고, 해당 함수를 props로 CardFilter 컴포넌트에 전달해주고 있다. 이때, 리렌더링 개선을 위해서는 React.memo를 통해 메모에제이션해 주어야 한다.

useCallback을 통해 MapPage가 리렌더링되더라도 함수가 재생성되지 않고, 같은 참조값을 가지게 된다. 동일한 참조값으로 props로 전달되어 얕은 비교가 되기 때문에, 상위 컴포넌트의 리렌더링으로 인한 CardFilter의 리렌더링은 발생하지 않게 된다.

export default memo(CardFilter);

🍊 개선 후

CardFilter 컴포넌트에서 3번의 리렌더링 발생

profile
start coding

0개의 댓글

관련 채용 정보