目的
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
続き
感想
- ES6で書き換えようかと思ったけどツラそう...
- flux のライブラリは何を使うのがいいのやら...