[react] Redux의 useSelector 최적화

eunbi·2020년 8월 11일
4

React

목록 보기
22/22

이 포스트는 https://react.vlpt.us/redux/08-optimize-useSelector.html 이 강의를 제가 다시 보기 위해 정리한 것입니다.

useSelector 최적화

useSelector는 리덕스 스토어의 상태를 조회하는 Hook이다.

state의 값은 store.getState() 함수를 호출했을 때 나타나는 결과물과 동일하다.

기본적으로, useSelector를 사용해서 리덕스 스토어의 상태를 조회 할 땐 상태가 바뀌지 않았으면 리렌더링하지 않는다.

const { number, diff } = useSelector(state => ({
  number: state.counter.number,
  diff: state.counter.diff
}));

하지만 위 코드처럼 useSelector Hook 을 통해 매번 렌더링 될 때마다 객체를 새로 만들게 되면 상태가 바뀌었는지 바뀌지 않았는지 확인을 할 수 없어서 낭비 렌더링이 이루어진다.

이것을 개선하기 위해서는 두가지 방법이 있다.

1. useSelector 를 여러번 사용하기

const number = useSelector(state => state.counter.number);
const diff = useSelector(state => state.counter.diff);

이렇게 하면 해당 값들 하나라도 바뀌었을 때에만 컴포넌트가 리렌더링 된다.

2. shallowEqual 함수를 useSelector의 두번째 인자로 전달

import React from 'react';
import { useSelector, useDispatch, shallowEqual } from 'react-redux';
import Counter from '../components/Counter';
import { increase, decrease, setDiff } from '../modules/counter';

function CounterContainer() {
  const { number, diff } = useSelector(
    state => ({
      number: state.counter.number,
      diff: state.counter.diff
    }),
    shallowEqual
  );

  (...)

useSelector 의 두번째 파라미터는 equalityFn 이다.

equalityFn?: (left: any, right: any) => boolean
이전 값과 다음 값을 비교하여 true가 나오면 리렌더링을 하지 않고 false가 나오면 리렌더링을 한다.

위 코드를 equalityFn로 비교해보면 아래와 같이 작성할 수 있다.

function CounterContainer() {
  const { number, diff } = useSelector(
    state => ({
      number: state.counter.number,
      diff: state.counter.diff
    }),
    (left, right) => {
    	return left.diff === right.diff && left.number === rifght.number;
    }
  );

매번 이렇게 비교하기는 힘드니까 shallowEqual가 그 역할을 대신 해준다.

shallowEqual은 react-redux에 내장되어있는 함수로서, 객체 안의 가장 겉에 있는 값들을 모두 비교해준다.

즉, 깊은 객체까지 비교해 주지는 못한다는 의미이다.

profile
프론트엔드 개발자입니다 :)

0개의 댓글