성별 여성 선택 => 적용하기 버튼 클릭 => 성별 남성 선택 => 적용하기 버튼 클릭 => 성별 모두 선택 => 적용하기 버튼 클릭
CardFilter 컴포넌트에서 12번의 리렌더링이 발생하였다.
지도페이지를 구성하는 MapPage 컴포넌트에는 CardFilter, SideBar, KakaoMap 이라는 하위 컴포넌트를 가진다.
CardFilter 컴포넌트는 날짜, 성별을 표시하는 컴포넌트이며, filterSubmit이라는 함수를 상위 컴포넌트에서 props로 전달받는다.
여기서 문제는
적용하기
버튼을 클릭할 때마다 MapPage의 filterInfo state가 업데이트됙,때문에, useCallback, React.memo를 통해 리렌더링을 개선하고자 하였다.
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는 컴포넌트를 메모이제이션하고, 얕은 비교를 통해 props가 변경되었을 경우 리랜더링된다.
위의 MapPage.jsx에서 useCallback으로 함수를 메모이제이션하였고, 해당 함수를 props로 CardFilter 컴포넌트에 전달해주고 있다. 이때, 리렌더링 개선을 위해서는 React.memo를 통해 메모에제이션해 주어야 한다.
useCallback을 통해 MapPage가 리렌더링되더라도 함수가 재생성되지 않고, 같은 참조값을 가지게 된다. 동일한 참조값으로 props로 전달되어 얕은 비교가 되기 때문에, 상위 컴포넌트의 리렌더링으로 인한 CardFilter의 리렌더링은 발생하지 않게 된다.
export default memo(CardFilter);
CardFilter 컴포넌트에서 3번의 리렌더링 발생