Redux


기본 개념

Redux의 3원칙

  1. Single Source of Truth
    아래에서 설명할 Flux와 다르게 Redux는 store를 단 1개만 사용합니다.
  2. State is Read-only
    state를 직접 변경할 수 없고, 변경하려면 action이 dispatch되어야 합니다.
  3. Changes are made with pure functions
    reducer는 오직 순수함수로 작성합니다.

Action

액션, 말그대로 동작입니다.
앱에서 어떤 부분이 변경되어야 하는지 정의합니다.
아래의 주문서 처럼 Object를 작성합니다.

// action
{
    type: 'ORDER',
    drink: {
        menu: '아메리카노',
        size: 'tall',
        iced: true
    }
}    

Action Creator

위의 Action을 좀 더 간편하게 생성하기 위해 만든 함수입니다.

액션 생성자가 액션을 생성하면 Dispatcher로 전달합니다.

// action creator
export function addTodo(text) {
  return { type: ADD_TODO, text }
}

export function completeTodo(index) {
  return { type: COMPLETE_TODO, index }
}

export function setVisibilityFilter(filter) {
  return { type: SET_VISIBILITY_FILTER, filter }
}

Dispatcher

액션을 받으면 액션을 읽고 어떤 부분을 업데이트할 지 결정합니다.

디스패처는 동기적으로 실행됩니다. 들어온 액션의 우선 순위대로 처리합니다.

// dispatch
dispatch(addTodo(text))
dispatch(completeTodo(index))
dispatch(setVisibilityFilter(filter))

Reducer

현재 상태와 액션을 이용해 다음 상태를 만들어냅니다.
Reducer는 순수 함수로 작성됩니다.
즉, 동일한 상태와 액션을 Reducer에 전달하면 항상 같은 상태가 나옵니다.
(prevState, action) => newState 와 같이 생각하시면 좋습니다 :)
절대, 인수를 변경하거나, API 호출, Date.now() 같은 메서드를 사용하시면 안됩니다!
Redux는 초기 상태를 undefined로 받으므로 초기 state를 지정해주어야 합니다.

// reducer
function todos(state = initialState, action) {
  switch (action.type) {
  case ADD_TODO:
    return ...
  case COMPLETE_TODO:
    return  ...
  default:
    return state;
  }
}

Store

상태가 관리되는 오직 하나의 공간입니다.
Redux를 사용하기 전에는 하위 컴포넌트로 props를 전달...전달...했었습니다.

스토어는 애플리케이션의 상태를 저장하고,
getState()를 통해 상태에 접근하게 하고,
dispatch(action)를 통해 상태를 수정할 수 있게 하고,
subscribe(listener)를 통해 리스너를 등록합니다.

Redux에서는 단 하나의 Store에 상태를 저장하고, Store에서 상태를 관리합니다.
사용법은 간단합니다. createStore에 reducer를 넣어주면 됩니다.

// store
import { createStore } from 'redux';
import todos from './reducers';

let store = createStore(todos);

Redux의 장점

  1. 상태를 예측할 수 있습니다.
  2. 유지 보수에 도움됩니다. (쉽게 생각해서, props 전달만 해도 간편하죠?)
  3. 디버깅에 유리하다.
  4. 테스트를 추가하기 쉽다. (순수 함수의 장점)

Flux

Redux의 구조와 Flux패턴은 조금 다른 부분이 있지만 이해하는데 도움이 됩니다.

순서를 보면서 Redux의 흐름도 다시 생각해봅니다.

준비

  1. Store가 Dispatcher에게 Action이 들어오면 말해달라고 합니다.
  2. View는 Store에게 state를 요청합니다.
  3. Store가 View에게 state를 주면, 모든 하위view에게 전달합니다.
  4. View는 Store에게 state가 변경될 때마다 알려달라고 요청합니다.

데이터 흐름

  1. View는 액션 생성자에게 액션을 생성해달라고 요청합니다.
  2. 액션 생성자는 액션을 생성하여 Dispatcher에 전달합니다.
  3. Dispatcher는 순서에 맞게 액션을 Store로 전달합니다.
  4. Store는 값을 업데이트하고, View에게 변경을 알리고 전달합니다.
  5. 그럼 다시 View는 모든 하위 View에게 전달하여 렌더링합니다.