あいつの日誌β

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

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

公式サイトのチュートリアルでは Todo App の Example が載っているのでそれを写経するのが良いのですがちょっと長いのでそれを短くした Memo アプリを紹介します。

準備

mkdir practice-react-redux && cd $_
mkdir src www test
mkdir src/{actions,components,containers,reducers}
npm init -f
npm install --save-dev mocha webpack webpack-dev-server
npm install --save-dev babel-core babel-loader babel-preset-es2015
npm install --save-dev babel-preset-stage-0 babel-polyfill
npm install --save-dev babel-preset-react

create webpack.config.js:

const path = require('path');
const webpack = require('webpack');

module.exports = { 
  entry: [path.resolve('src/index.js')],
  output: {
    path: path.resolve('www'),
    filename: 'bundle.js',
  },  
  devtool: 'inline-source-map',
  devServer: {
    contentBase: path.resolve('www'),
    port: 3000,
    hot: false,
    inline: true,
    colors: true
  },  
  resolve: {
    extensions: ['', '.js'],
  },  
  module: {
    loaders:[
      { test: /\.js$/, exclude: /node_modules/, loader: 'babel' },
    ]   
  }
};

create babelrc:

{ 
  "presets": ["react", "es2015", "stage-0"] 
}

install

npm install --save react react-redux redux

action を定義

create src/actions/index.js:

let nextId = 1 

export const addMemo = (text) => {
  return {
    type: 'ADD_MEMO',
    id: nextId++,
    text
  }
}

reducer を定義

create src/reducers/index.js

import { combineReducers } from 'redux'

const memo = (state = {}, action) => {
  switch (action.type) {
    case 'ADD_MEMO':
      return {
        id: action.id,
        text: action.text
      }
    default:
      return state
  }
}

const memos = (state = [], action) => {
  switch (action.type) {
    case 'ADD_MEMO':
      return [
        ...state,
        memo(undefined, action)
      ]
    default:
      return state
  }
}

const memoApp = combineReducers({
  memos
})

export default memoApp                 

ここまで作った部分は redux の箇所なのでテストします。途中で動作確認しないで写経すると効率が悪いので。ここではブラウザでテストするの面倒なので node でテストしています。

crete test/test_reducers.js

import assert from 'assert'
import { createStore } from 'redux'
import { addMemo } from '../src/actions'
import memoApp from '../src/reducers'

describe('test', () => {
  it('store', () => {
    let store = createStore(memoApp)

    store.dispatch(addMemo('textA'))
    store.dispatch(addMemo('textB'))
    assert.deepEqual(store.getState().memos, [ { id: 1, text: 'textA' }, { id: 2, text: 'textB' } ]); 

    assert.ok(true);
  }); 
});

実行します。

% NODE_ENV=test $(npm bin)/mocha --compilers js:babel-register

package.json に記述して npm test できるようにしておくと良いでしょう。

まとめ

という事で何となく action と reducers を定義して dispatch(addMemo(value))store.getState() をどこかに書けばデータの受け渡しができそうですね。

次回へ続く