리듀서

액션은 무언가 일어난다는 사실을 기술하지만, 그결과 앱의 상태가 어떻게 바뀌는지는 상관하지 않는다. 이부분은 리듀서가 담당한다. 리듀서는 이전상태와 액션을 받아 다음상태를 반환하는 순수함수 이다.

(prevState, action) => newState

순수함수에서는 아래와 3가지를 절대로 해서는 안된다.

  • 인수를 변경(mutate state)
  • API호출이나 라우팅등 사이드이팩트
  • Date.now()Math.random()같이 순수하지 않은(불량하게 값이 매번 다른) 함수 호출하기

리듀서는 반드시 순수해야 하며 인수가 주어지면 다음상태를 계산해서 반환해야한다. 그값은 당연히 예상가능해야하고 예상치 못한일이 일어나면 안된다.(assign메소드는 구현되지 않은 브라우저도 많기 때문에 _.assign()을 사용하면 된다.)

import {ADD_TODO, REMOVE_TODO}'../actions/types'

function reducer (state, {todo}) {
  switch (action.type) {
    case ADD_TODO :
      return Object.assign({}, state, {todo})
    case REMOVE_TODO :
      return Objevt.assign({}, state, {todo: null})
  }
}

예) spread_operator를 사용한 조금 안익숙한 reducer

function calendar (state = initialCalendarState, action) {
  const { day, recipe, meal } = action

  switch (action.type) {
    case ADD_RECIPE :
      return {
        ...state,
        [day]: {
          ...state[day],
          [meal]: recipe.label,
        }
      }
    case REMOVE_FROM_CALENDAR :
      return {
        ...state,
        [day]: {
          ...state[day],
          [meal]: null,
        }
      }
    default :
      return state
  }
}

여러개의 리듀서관리 하기

이런식으로 할 수도 있고

export default function todoApp(state, action) {
  return {
    visibilityFilter: visibilityFilter(state.visibilityFilter, action),
    todos: todos(state.todos, action)
  };
}

이런식으로 파일을 따로 만들어(index.js) 리듀서들을 가져와 관리 할 수도 있다.

import { combineReducers } from 'redux';

const todoApp = combineReducers({
  visibilityFilter,
  todos
});

export default todoApp;

이 두가지는 완전히 같은 의미의 코드이다.

results matching ""

    No results matching ""