目的
redux-thunk でどのように非同期処理をするのか試してみる。
カウンターの処理は以前書いたものを流用(ReactJS + Redux + ES6 のカウンターのサンプル)
ファイル構成
.
├── dest
│ └── bundle.js
├── index.html
├── package.json
└── src
└── app.jsx
package
pacage.json
{
"name": "react-flux-redux-thunk",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"watch": "watchify src/app.jsx -o dest/bundle.js -v --debug",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-preset-es2015": "^6.6.0",
"babel-preset-react": "^6.5.0",
"babelify": "^7.2.0",
"browserify": "^13.0.0",
"watchify": "^3.7.0"
},
"dependencies": {
"react": "^15.0.1",
"react-dom": "^15.0.1",
"react-redux": "^4.4.5",
"redux": "^3.4.0",
"redux-thunk": "^2.0.1"
},
"browserify": {
"transform": [
[
"babelify",
{
"presets": [
"es2015",
"react"
]
}
]
]
}
}
インストールとビルド
$ npm install
$ npm run watch
code
src/app.jsx
import React, { PropTypes } from 'react';
import thunk from 'redux-thunk';
import { render } from 'react-dom';
import { applyMiddleware, createStore } from 'redux';
import { Provider, connect } from 'react-redux';
// Action
function actionIncrement() {
return {
type: 'INCREMENT',
count: 1
};
}
function actionIncrementAsync() {
return dispatch => {
setTimeout(() => {
dispatch(actionIncrement());
}, 1000);
};
}
function actionDecrement() {
return {
type: 'DECREMENT',
count: -1
};
}
function actionDecrementAsync() {
return dispatch => {
setTimeout(() => {
dispatch(actionDecrement());
}, 1000);
};
}
// Reducer
function counterReducer (state = {count: 0}, action) {
let count = state.count;
switch (action.type) {
case 'INCREMENT':
return {count: count + action.count};
case 'DECREMENT':
return {count: count + action.count};
default:
return state;
}
}
// Component
class CounterComponent extends React.Component {
render () {
const { count, onClickPlus, onClickMinus } = this.props;
return (
<div>
<p><span>Count: {count}</span></p>
<div>
<button onClick={onClickPlus}>+1</button>
<button onClick={onClickMinus}>-1</button>
</div>
</div>
);
}
}
CounterComponent.propTypes = {
count: PropTypes.number.isRequired,
onClickPlus: PropTypes.func.isRequired,
onClickMinus: PropTypes.func.isRequired,
};
// Containers
function mapStateToPropsContainer(state) {
return {
count: state.count
};
}
function mapDispatchToPropsContainer(dispatch) {
return {
onClickPlus: () => dispatch(actionIncrementAsync()),
onClickMinus: () => dispatch(actionDecrementAsync()),
};
}
let App = connect(
mapStateToPropsContainer,
mapDispatchToPropsContainer
)(CounterComponent);
// main
let store = createStore(
counterReducer,
applyMiddleware(thunk)
);
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('app-container')
);
表示
$ python -m SimpleHTTPServer 3000
ボタンを押すと1秒遅れて表示にカウント数が変わる