ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React - reselect 사용하기
    React/라이브러리 2020. 8. 31. 23:37

     

     

    들어가기에 앞서, 우선 Selector를 먼저 알아야 한다.

     

    Selector는 무엇인가?

    selector는 state에서 필요한 데이터를 가져오거나, 계산을 수행해서 원하는 형태의 데이터를 가져오는 역할을 말한다.

    왜 써야 하는가?

    다음 예제를 살펴보자.

    todoApp 리듀서와 getIncompleteTodos selector가 존재한다.

    // Reducer
    function todoApp(state = [], action) {
     switch (action.type) {
       case GET_ALL_TODOS:
         return {
           todos: action.data.todos
         };
       default:
         return state;
     }
    }
    // Selector
    function getIncompleteTodos(state) {
      return state.todos.filter((todo) => {
        return !todo.completed
      });
    }

    만약 어떠한 컴포넌트에서 mapStateToProps()를 사용한다면,

    // 어떠한 컴포넌트
    function mapStateToProps (state) { 
      return { 
        incompleteTodos : state.todos.filter ((todo) => { 
          return! todo.completed 
        }); 
      } 
    }

    밑에 처럼 incompleteTodos에 새로 만든 selector를 사용해서 바꿀 수 있다.

    function mapStateToProps (state) { 
      return { 
        incompleteTodos : getIncompleteTodos (state) 
      }; 
    }

    이처럼 selector는 Redux가 적은 양의 필요한 데이터만을 가지고 있게 데이터에 대한 계산을 도와주며,

    state를 가져오는 컴포넌트들과 state의 구조 사이 한 층(selector)을 두어 구조가 바뀌어도 연관된 모든 컴포넌트를 바꿀 필요 없이 selector만 바꿔주면 성능이 향상되기 때문에 사용한다.

     

    그렇다면 reselect란 무엇인가?

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

    쓰는 이유는 무엇인가?

    일반적으로 selector를 한 파일에 보관하고 관리하는데, 이때 한 파일 내에 있는 selector가 갱신되면 다른 selector도 갱신된다고 한다.

    즉, 필요하지 않은 만큼 많은 컴포넌트 렌더링이 발생하게 된다.

    이럴 때 reselect가 memoization를 통해 불필요한 렌더링을 막아주고 성능을 향샹시켜주시 때문에 사용해야 한다. 

    여기서 memoization(메모화)란?

    함수에 대한 입력을 추적하고 나중에 참조할 수 있도록 입력과 결과를 저장하는 작업을 말한다.

    즉, 이전과 동일한 입력으로 함수를 호출하면 함수는 실제 작업을 건너뛰고 해당 입력 값을 마지막으로 수신했을 때 생성한 것과 동일한 결과를 반환하는 작업을 말한다.

     

    어떻게 써야하는가?

    이번에 진행했던 고피자 프로젝트에서 reselect를 사용해보았다.

    CartIcon.tsx 파일

    이 컴포넌트는 장바구니에 상품이 추가되거나 삭제될 때마다 수량이 변하는 것과 누르면 드롭박스를 보여주는 기능을 한다.

    우선 import 한 모듈들 중에 생소한 것들을 짚고 넘어가 보도록 하자.

    import { createStructuredSelector } from 'reselect';

    이 부분은 selector를 효율적으로 사용하기 위한 메서드이다.

    createStructuredSelectorreselector를 더 편하게 쓰게 해주는 메서드 중 하나이며, 이걸 쓰면 뒤에 들어오는 selector에 state를 인자로 넣어주지 않아도 되기 때문에 사용했다.

    여기에서 인자로 들어간 selectCartHidden과 selectCartItemsCount의 값은 selector에 있는 state를 가져온 값이며, 해당 컴포넌트에서 사용할 수 있는 state가 된다.

     

    selector들이 존재하는 cartSelector.ts 파일

    여기서 createSelector는 reselect에서 불러온 메서드다. 위에서 설명했던 것처럼 memoization를 통해 불필요한 랜더링을 막는 역할을 한다. 

    1. state에서 cart를 불러내서 selectCart에 담고 selectCart에서 hidden을 불러낸 후, selectCartHidden에 해당 state를 담았다.
    2. 똑같은 방식으로 selectCartItems를 가지고 reduce()을 이용하여 카트에 담긴 상품의 수량을 반환한 값을 selectCartItemsCount에 담았다.

    이렇게 반환된 값은 해당 컴포넌트 안에서 hidden, itemCount이라는 이름의 state로 사용하는 것을 볼 수 있다.

     

    🎈 정리!

    이 예시들을 통해 앞에서 말한 state에서 필요한 데이터를 가져오거나, 계산을 수행해서 원하는 형태의 데이터를 가져와서 사용되는 selector들을 볼 수 있다.

    또, reselect의 memoization를 통해 불필요한 렌더링을 막아줘 성능이 향상된 것을 확인할 수 있었다.

    아직 저 또한 이 기술이 많이 생소하지만, 기술을 쓸 때 왜 쓰이지는를 알고 써야 나중에 또 쓸 수 있기 때문에 부족하지만 이렇게 정리해보았다.

    혹시 잘못된 정보가 있으면 꼭 피드백 주길 바란다.

     

    'React > 라이브러리' 카테고리의 다른 글

    React - Font Awesome과 Toastify 사용하기  (0) 2020.05.26

    댓글

Designed by Tistory.