LoginSignup
15
16

More than 5 years have passed since last update.

ReactJS + facebook/flux でカウンターのサンプル

Last updated at Posted at 2015-07-04

目的

Web+DB Press Vol.87 の Flux の記事 が素晴らしかったので、facebook/flux で書き換えてみた。
(記事では fluxxor

ちなみに雑誌のサンプルコードは こちらの「Emerging Web Technology研究室」

下記todoサンプルを参考にした
- [https://github.com/facebook/flux/tree/master/examples/flux-todomvc]

ファイル構成

.
├── dest
│   └── app.js
├── index.html
├── package.json
└── src
    ├── app.jsx
    └── app_dispatcher.js

package

reactify ではなく babelify を使う

pacage.json
{
  "devDependencies": {
    "babelify": "^6.1.2",
    "browserify": "^10.2.4",
    "watchify": "^3.2.3"
  },
  "scripts": {
    "watch": "watchify -t babelify src/app.jsx -o dest/app.js -v"
  },
  "dependencies": {
    "flux": "^2.0.3",
    "keymirror": "^0.1.1",
    "object-assign": "^3.0.0",
    "react": "^0.13.3"
  }
}

$ npm install
$ npm run watch

code

src/app.jsx
var EventEmitter = require('events').EventEmitter;
var React = require('react');
var assign = require('object-assign');
var keyMirror = require('keymirror');

var AppDispatcher = require('./app_dispatcher');

var CounterConstants = keyMirror({
    UPDATE_COUNTER: null
});


// Store
var CHANGE_EVENT = 'change';
var counter = 0;

var CounterStore = assign({}, EventEmitter.prototype, {
    getCounter: function() {
        return counter;
    },
    emitChange: function() {
        this.emit(CHANGE_EVENT);
    },
    addChangeListener: function(callback) {
        this.on(CHANGE_EVENT, callback);
    },
    onUpdateCounter: function(value) {
        counter += value;
    }
});

AppDispatcher.register(function(action) {
    switch(action.actionType) {
        case CounterConstants.UPDATE_COUNTER:
            CounterStore.onUpdateCounter(action.value);
            CounterStore.emitChange();
            break;
        default:
            // no op
    }
});


// Action
var CounterActions = {
    plusCounter: function() {
        AppDispatcher.dispatch({
            actionType: CounterConstants.UPDATE_COUNTER,
            value: 1
        });
    },
    minusCounter: function() {
        AppDispatcher.dispatch({
            actionType: CounterConstants.UPDATE_COUNTER,
            value: -1
        });
    }
};


// View
function getCounterState() {
    return {
        value: CounterStore.getCounter()
    };
}

var CounterAppView = React.createClass({
    getInitialState: function() {
        return getCounterState();
    },
    componentDidMount: function() {
        CounterStore.addChangeListener(this.onChange);
    },
    render: function() {
        return (
            <div>
                <span>count: {this.state.value}</span>
                <CounterView />
            </div>
        );
    },
    onChange: function() {
        this.setState(getCounterState());
    }
});

var CounterView = React.createClass({
    render: function() {
        return (
            <div>
                <div>
                    <button onClick={this.onClickPlus}>+1</button>
                    <button onClick={this.onClickMinus}>-1</button>
                </div>
            </div>
        );
    },
    onClickPlus: function() {
        CounterActions.plusCounter();
    },
    onClickMinus: function() {
        CounterActions.minusCounter();
    }
});

React.render(
    <CounterAppView />,
    document.getElementById('app-container')
);
src/app_dispatcher.js
var Dispatcher = require('flux').Dispatcher;

module.exports = new Dispatcher();
index.html
<!doctype html>
<html lang="ja">
    <head>
        <meta charset="utf-8">
        <title>Flux</title>
    </head>
    <body>
        <div id="app-container"></div>

        <script src="dest/app.js"></script>
    </body>
</html>

表示

$ python -m SimpleHTTPServer 8000

スクリーンショット 2015-07-03 0.20.12.png

続き

感想

  • ES6で書き換えようかと思ったけどツラそう...
  • flux のライブラリは何を使うのがいいのやら...

参考

15
16
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
15
16