LoginSignup
20
20

More than 5 years have passed since last update.

ReactJS + facebook/flux を ES6 の記述でカウンターのサンプル

Last updated at Posted at 2015-07-05

追記:2016-01-20

改めて見たら冗長・間違ってた・アプデで動かないとかだったので、テスト書く勉強のついでにリファクタした。

下記は記録的にとりあえず残しておく。

目的

前回の続き

class などを使って書き換えてみる。

ファイル構成

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

package

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",
    "react": "^0.13.3"
  }
}
$ npm install
$ npm run watch

code

src/app.jsx
import {EventEmitter} from 'events';
import React from 'react';
import AppDispatcher from './app_dispatcher';

const COUNTER_CONST = {
    UPDATE_COUNTER: 'UPDATE_COUNTER'
};

// Store
let SINGLETON = Symbol();
let SINGLETON_ENFORCER = Symbol();


class CounterStoreSingleton extends EventEmitter {
    constructor(enforcer) {
        super();

        if (enforcer !== SINGLETON_ENFORCER) {
            throw "Cannot construct singleton";
        }

        AppDispatcher.register(this._onAction.bind(this));

        this.counter = 0;
        this.CHANGE_EVENT = 'change';
    }

    static get instance() {
        if (!this[SINGLETON]) {
            this[SINGLETON] = new CounterStoreSingleton(SINGLETON_ENFORCER);
        }
        return this[SINGLETON];
    }
    _onAction(action) {
        switch(action.actionType) {
            case COUNTER_CONST.UPDATE_COUNTER:
                CounterStore.onUpdateCounter(action.count);
                CounterStore.emitChange();
                break;
            default:
                // no op
        }
    }
    emitChange() {
        this.emit(this.CHANGE_EVENT);
    }
    updateChangeListener(callback) {
        this.on(this.CHANGE_EVENT, callback);
    }
    getCount() {
        return {count: this.counter};
    }
    onUpdateCounter(count) {
        this.counter += count;
    }
}
let CounterStore = CounterStoreSingleton.instance;


// Action
let CounterActions = {
    plusCounter: function() {
        AppDispatcher.dispatch({
            actionType: COUNTER_CONST.UPDATE_COUNTER,
            count: 1
        });
    },
    minusCounter: function() {
        AppDispatcher.dispatch({
            actionType: COUNTER_CONST.UPDATE_COUNTER,
            count: -1
        });
    }
};


// View
class CounterAppView extends React.Component {
    constructor() {
        super();
        this.state = CounterStore.getCount();
        this._onChange = this._onChange.bind(this);
    }
    componentDidMount() {
        CounterStore.updateChangeListener(this._onChange);
    }
    render() {
        return (
            <div>
                <span>count: {this.state.count}</span>
                <CounterView />
            </div>
        );
    }
    _onChange() {
        this.setState(CounterStore.getCount());
    }
}

CounterAppView.propTypes = {
    count: React.PropTypes.number
};


class CounterView extends React.Component {
    render() {
        return (
            <div>
                <div>
                    <button onClick={this.onClickPlus}>+1</button>
                    <button onClick={this.onClickMinus}>-1</button>
                </div>
            </div>
        );
    }
    onClickPlus() {
        CounterActions.plusCounter();
    }
    onClickMinus() {
        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

感想

参考

20
20
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
20
20