29
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ReactJS + Redux + redux-thunk で非同期のカウンターのサンプル

Last updated at Posted at 2016-04-17

目的

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

スクリーンショット 2015-11-07 14.48.21.png

ボタンを押すと1秒遅れて表示にカウント数が変わる

参考

29
25
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
29
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?