Redux 내용정리

ys_sung blog·2021년 4월 26일
0

https://www.robinwieruch.de/react-redux-tutorial 의 'React Redux Tutorial for Beginners [2019]'를 읽고 개인적으로 학습하고 요약 정리한 내용입니다.

JS 라이브러리의 간단한 역사

  • 예전에는 자바스크립트 라이브러리로 jQuery가 유일했었다. DOM을 조작할 수 있었고, 위젯을 재사용하고 애니메이션 효과를 줄 수 있는 유용한 라이브러리였다.

  • 하지만 어플리케이션의 사이즈가 커져가면서 JS코드의 사이즈가 커졌었고 이것은 스파게티 코드를 작성하게 되는 요인이 되기도 했다.

  • 이런 jQuery의 한계를 극복하기 위한 프레임워크(또는 라이브러리)가 등장했다. 이것들은 더 나은 아키텍쳐를 제공하고 특히 문제를 해결하기 위해 개발자가 SPA(Single Page Applicateion)로 프론트엔드 어플리케이션을 만들 수 있도록 하였다.

  • Angular, Ember, Backbone과 같은 프레임워크들이 그렇게 급부상했다. 하지만 어플리케이션의 사이즈가 증가하면서 이러한 것들도 새로운 한계에 부딪혔다. 그것은 바로 상태 관리(State Management)이다. 이런 프레임워크들은 상태를 양방향으로 관리하기 때문에 규모가 커질 수록 상태 관리에 애를 먹었던 것이다.

  • 그래서 등장한 것이 React이다. React는 이전의 프레임워크와 달리 View Layer만 영향을 미쳤는데, 이런 React가 상태를 관리하는 법은 Local State를 활용하는 방법이었다. React에서 State는 상위에서 하위로 흐르는 단방향이기 때문에 코드의 결과를 더 예측하기가 쉬웠다.

  • 하지만 역시 상태 관리 문제가 여전히 해결된 건 아니었다. 이전의 프레임워크만큼 심각한 문제는 아니지만 여전히 React에서도 문제가 남아있었다.

  • React를 만든 페이스북에서는 이런 문제를 해결하기 위해 Flux Architecture를 소개한다.

Flux Architecture

  • Flux Architecture는 Action, Dispatcher, Store, View라는 네가지 핵심 요소로 이루어진다.

  • 네 가지 요소가 상호작용하는 과정은 다음과 같다.

    1. 사용자는 브라우저에서 View에 상호작용(ex. 클릭)을 함으로써 Action을 트리거한다.
    2. Action은 State를 업데이트하는 데 필요한 정보를 갖고 있다.
    3. Dispatcher는 Action을 스토어에 전달한다.
    4. 새로운 State가 Store에 전달된다
    5. View 업데이트!
  • 이렇게 보듯이 데이터는 단방향으로 흐른다. View에서 Action을 트리거해서 Dispatcher와 Store에 전달되고, 최종적으로 View는 새로운 상태를 반영한다.

Redux(Reducer + Flux)

  • 리덕스는 Flux Architecture의 많은 부분을 차용했지만 모든 것은 아니다.

  • 예를 들어 리덕스의 Store는 singletone이다. 한 프로젝트에 Store는 하나만 존재한다. 반면에 Dispatcher는 하나가 아니었다. 리덕스에서는 대신 여러개의 Reducer를 사용했다. 이 Reducer가 Action을 전달받아서 State를 변화시킨다.

Redux의 요소들

Action
  • type과 payload로 이루어져 있다.(payload는 optional)
  • type는 Reducer가 액션을 구분하기 위해 사용하며 문자열이다.
  • payload는 어떤 타입이든 상관없다. 변화시킬 state의 본문(내용)이다.
  • Action은 Reducer 함수에 전달된다.
Reducer
  • 리듀서는 오직 action type만 해석할 수 있다.
  • Switch/Case 문을 이용해서 type을 분기한다.
  • default 문을 이용해서 state가 변화하지 않는 조건문 작성한다.
  • 각 조건문 안에서 state에 변화를 주는 로직 작성한다.
  1. to-do-list 추가의 경우: concat으로 불변성 유지하면서 배열에 요소 추가
  2. toggle-switch의 경우: 액션의 payload로 전달받은 id와 map메소드(immutable)를 이용해서 사용해서 배열에서 해당 id를 갖는 요소를 찾아서 해당 요소를 변경시켜준다(여전히 immutable하게! Object.assign 사용)
  • Reducer 함수를 간략하게 만드려면 Case문 내부의 로직을 바깥의 함수로 추출해내면 된다.
Store
  • 앞서 본 Action(state를 트리거)과 Reducer(이전 state와 action에 새로운 state를 첨가)하는 로직들을 아우르는 역할을 한다.
  • 질문들
    1. 어디서 action을 trigger하는가
    2. 누가 reducer에 action을 전달하는가
    3. 뷰에 업데이트된 state를 반영하기 위해서 state를 어디서 가져와야 하는가
  • 답은 모두 Redux Store다!
  • Store는 flux와 다르게 프로젝트에서 하나만 존재하는 Global Object다.
//스토어는 리덕스에서 import해서 가져온다.
//createStore함수는 reducer를 인자로 받는다. 두번째 인자는 state의 초기값
//리액트와 리덕스를 같이 사용할 때는 아래와 다른 방식으로 초기값을 설정한다: 스토어가 아니라 리듀서 함수에서 초기값 설정
import { createStore } from 'redux';
const store = createStore(reducer, []);
  • Store로 할 수 있는 것들
store.dispatch(action)
//액션을 dispatch할 수 있다.(state update)
store.getState()
//현재 state를 읽어올 수 있다.
const unsubscribe = store.subscribe() unsubscribe() 
//state의 변화를 view에 반영하거나 반영하지 않게 할 수 있다

0개의 댓글