react-redux, reselect 패키지

kangdari·2020년 8월 25일
0

react-redux 패키지

npm install react-redux

Provider 컴포넌트

Provider 컴포넌트 하위에 있는 컴포넌트는 리덕스의 상태 값이 변경되면 자동으로 컴포넌트 함수가 호출되도록 할 수 있다. store 객체를 Provider의 속성 값으로 전달.

// ...

import store from './Common/store';
import { Provider } from 'react-redux';

ReactDOM.render(
  <Provider store={store}>
    <div>
      <FriendMain />
      <TimeLineMian />
    </div>
  </Provider>,
  document.getElementById('root')
);

Provider 컴포넌트는 전달받은 스토어 객체의 subscribe 메서드를 호출해서 액션 처리가 끝날 때 알림을 받고 Context API를 사용해서 리덕스의 상태 값을 하위 컴포넌트에 전달한다.

useSelector, useDispatch

import { useSelector, useDispatch } from 'react-redux';
// ...
  const friends = useSelector((state) => state.friend.friends);
  const dispatch = useDispatch();
  // ...

useSelector 훅에 입력되는 함수를 선택자 함수라고 하며, 이 함수가 반환하는 값이 훅의 반환값으로 사용된다. useSelector 훅은 리덕스의 상태 값이 변경되면 이전 반환 값과 새로운 반환 값을 비교. 두 값이 다른 경우에만 컴포넌트를 다시 렌더링한다.

useDispatch 훅은 액션을 발생시키는 dispatch 함수를 반환한다.

useSelector 훅으로 여러 상태 값 반환하기

useSelector 훅으로 여러 상태 값을 가져오려면 선택자 함수가 객체를 반환해야 한다.

  • useSelector 훅을 필요한 상태 값 개수만큼 사용
    ( 성능 문제는 없으므로 사용해도 상관 없음. )
  • 메모제이션 이용
  • useSelector 훅의 두 번째 매개변수를 활용

useSelector 훅의 두 번째 매개변수는 컴포넌트 렌더링 여부를 판단하는 역할을 한다. 이 매개변수가 없는 경우 참조 값만 비교하는 단순 비교 함수가 사용됨. 따라서 선택자 함수가 객체 리터럴을 반환하면 컴포넌트가 불필요하게 렌더링되는 문제가 발생. 이 때 react-redux의 shallowEqual 함수를 이용할 수 있다.

shallowEqual 사용법

import { shallowEqual } from 'react-redux';

export default function Component() {
  const [value1, value2, value3] = useSelector(
    (state) => [state.value1, state.value2, state.value3],
    shallowEqual,
  );
}

useSelector 훅의 선택자 함수가 여러 상태 값을 배열에 담아 반환한다. shallowEqual 함수는 배열의 각 원소가 변경됐는지 검사한다.

reselect 패키지

리덕스에서 저장된 데이터를 화면에 보여줄 때는 다양한 형식으로 가공할 필요가 있다. (정렬, 필터 등...) reselect 패키지는 원본 데이터를 다양한 형태로 가공해서 사용할 수 있도록 도와준다.

npm install reselect

import { createSelector } from 'reselect';

// 상태 값을 전달 하는 함수
const getFriends = (state) => state.friend.friends;
const getAgeLimit = (state) => state.friend.ageLimit;
const getShowLimit = (state) => state.firend.showLimit;

export const getFirendsWithAgeLimit = createSelector(
  [getFriends, getAgeLimit],
  (friends, ageLimit) => friends.filter((friend) => friend.age <= ageLimit)
);

export const getFriendsWithAgeShowLimit = createSelector(
  [getFirendsWithAgeLimit, getShowLimit],
  (firendsWithAgeLimit, showLimit) => firendsWithAgeLimit.slice(0, showLimit)
);

createSelector 함수를 이용해서 선택자 함수를 만든다.

getFirendsWithAgeLimit 함수는 연령 제한이 적용된 친구 목록을 보여주는 함수로
createSelector 함수의 첫 번째 매개변수로 함수가 담긴 배열을 전달한다. 각 함수에서 반환한 값이 createSelector의 두 번째 매개변수 함수의 인자 값으로 전달된다.

reselect 패키지는 메모제이션 기능이 있다. 즉, 연산에 사용되는 데이터가 변경되는 경우에만 연산을 수행하고, 변경되지 않은 경우네는 이전 결과 값을 그대로 사용한다.
getFirendsWithAgeLimit 함수의 경우 friends, ageLimit 값이 변경되는 경우에만 연산을 한다.

선택자 함수 사용

import {
  getAgeLimit,
  getShowLimit,
  getFirendsWithAgeLimit,
  getFriendsWithAgeShowLimit,
} from '../state/selector';
// ...
  const [ageLimit, showLimit, friendsWithAgeLimit, friendsWithAgeShowLimit] = useSelector(
    (state) => [
      getAgeLimit(state),
      getShowLimit(state),
      getFirendsWithAgeLimit(state),
      getFriendsWithAgeShowLimit(state),
    ],
    shallowEqual
  );

shallowEqual 함수를 사용해 한번에 사용할 수도 있고

  const ageLimit = useSelector(getAgeLimit);
  const showLimit = useSelector(getShowLimit);
  const friendsWithAgeLimit = useSelector(getFirendsWithAgeLimit);
  const friendsWithAgeShowLimit = useSelector(getFriendsWithAgeShowLimit);

useSelector 훅에 선택자 함수만 입력하는 방식도 있다.

0개의 댓글