Redux selector 리렌더링 최적화

리덕스에서 스토어에 변경이 생기면(dispatch가 일어나면) 기본적으로 useSelector훅을 사용한 모든 컴포넌트의 useSelector의 인자와 store의 state와 비교하여 다르면 리렌더링된다.

하지만 state가 primitive value가 아닌 객체,배열 등이라면 실제 값들은 바뀌지 않았다 하더라도 다른 객체로 인식하여 리렌더링된다.

해결방법

  1. useSelector를 여러번으로 나누어서 쓴다.
{
	id:'1'
  name: 'choi'
}

예를 들어 store에 저장하는 currentUser정보가 위와 같을 때

user state를 사용하는 컴포넌트에서

const userId=useSelect(state=>state.user.currentUser.id);
const userName=useSelect(state=>state.user.currentUser.name);

이렇게 사용한다면 currentUser가 변경되는게 아닌 이상 리렌더링이 될 일이 없다.

그렇지만 저렇게 사용하는건 너무 가독성이 떨어진다.

2.useSelector의 두번째 파라미터에 equalityFn을 직접 넣는다.

equalityFn?: (left: any, right: any) => boolean

이전 값(left)과 다음 값(right)를 비교하여 true가 나오면 리렌더링 하지 않고 false이면 리렌더링한다.

위의 예시로는

const currentUser=useSelect(state=>state.user.currentUser,
			(left,right)=>left.id===right.id&&left.name===right.name);

3.Reselect library 활용

selector 역할을 수행하면서 캐싱을 통해 동일한 계산을 방지해서 성능을 향상시켜 주며, 파라미터로 전달받은 값이 이전과 같다면 새롭게 계산하지 않고 저장된 결과 값을 돌려주는 라이브러리

import {createSelector} from 'reselect'

const selectUserReducer=(state)=>state.user;

const selectCurrentUser = createSelector(
	[selectUserReducer],
	(userSlice) = > userSlice.currentUser
);

const currentUser=useSelect(selectCurrentUser);

좋은 웹페이지 즐겨찾기