あいつの日誌β

働きながら旅しています。

Redux.js を最速で試す(2)

前回の続きです。 http://okamuuu.hatenablog.com/entry/2016/10/06/160721

準備

create src/actions.js:

/*
 * action types
 */

export const ADD_TODO = 'ADD_TODO'
export const TOGGLE_TODO = 'TOGGLE_TODO'
export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER'

/*
 * other constants
 */

export const VisibilityFilters = {
  SHOW_ALL: 'SHOW_ALL',
  SHOW_COMPLETED: 'SHOW_COMPLETED',
  SHOW_ACTIVE: 'SHOW_ACTIVE'
}

/*
 * action creators
 */

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

export function toggleTodo(index) {
  return { type: TOGGLE_TODO, index }
}

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

create reducers.js:

import { combineReducers } from 'redux'
import { ADD_TODO, TOGGLE_TODO, SET_VISIBILITY_FILTER, VisibilityFilters } from './actions'
const { SHOW_ALL } = VisibilityFilters

function visibilityFilter(state = SHOW_ALL, action) {
  switch (action.type) {
    case SET_VISIBILITY_FILTER:
      return action.filter
    default:
      return state
  }
}

function todos(state = [], action) {
  switch (action.type) {
    case ADD_TODO:
      return [
        ...state,
        {
          text: action.text,
          completed: false
        }
      ]
    case TOGGLE_TODO:
      return state.map((todo, index) => {
        if (index === action.index) {
          return Object.assign({}, todo, {
            completed: !todo.completed
          })
        }
        return todo
      })
    default:
      return state
  }
}

const todoApp = combineReducers({
  visibilityFilter,
  todos
})

export default todoApp

update src/app.js

import { addTodo, toggleTodo, setVisibilityFilter, VisibilityFilters } from './actions'

// Log the initial state
console.log(store.getState())

// Every time the state changes, log it
// Note that subscribe() returns a function for unregistering the listener
let unsubscribe = store.subscribe(() =>
  console.log(store.getState())
)

// Dispatch some actions
store.dispatch(addTodo('Learn about actions'))
store.dispatch(addTodo('Learn about reducers'))
store.dispatch(addTodo('Learn about store'))
store.dispatch(toggleTodo(0))
store.dispatch(toggleTodo(1))
store.dispatch(setVisibilityFilter(VisibilityFilters.SHOW_COMPLETED))

// Stop listening to state updates
unsubscribe()

実行

$(npm bin)/webpack && node www/bundle.js

強引に言うと action.js と reducer.js では「setter と getter を定義しています」

src/app.js ではその setter と getter の使用例と subscribe 関数が紹介されています。 store.subscribe() の引数には callback を渡す事ができます。その callback は store が update されるたびに実行されます。

store.subscribe() の返り値はそれを停止する関数です。 https://github.com/reactjs/redux/blob/master/src/createStore.js#L111

action と reducer の概念については使い続けてれば勝手に覚えるので(たぶん)取り急ぎこんな覚え方しておいて次行ってしまいましょう。

ここに書いてあるソースコードは全部こちらから拝借しています。

http://redux.js.org/docs/basics/Actions.html http://redux.js.org/docs/basics/Reducers.html http://redux.js.org/docs/basics/Store.html