EventEmitterバケツリレースタイル/フレームワークなしで小さくFluxする - Qiita
これ見て最近は大体自分も同じような感じのことをしているので共通化できる最小限のコードをライブラリにしてみた。
元記事でも言ってるようにやることはとても少ないのでライブラリ使わないでもいいんだけどそのへんは好み。
Usage
まず普通のステートレスなReactコンポーネントを作る。dispatch
というprops
を受け取ってそれを通してイベントを発火するというのが唯一の規約。
import React from 'react';
// Stateless component
export default class Counter extends React.Component {
render() {
return (
<div>
<div>{this.props.count}</div>
<button onClick={() => this.props.dispatch('increment', 1)}>+1</button>
<button onClick={() => this.props.dispatch('decrement', 1)}>-1</button>
<button onClick={() => this.props.dispatch('increment', 100)}>+100</button>
</div>
);
}
}
それをwrapするコンテナコンポーネントを作る。こいつはstateを持ち、子のコンポーネントにdispatch
を渡してイベントをsubscribeし、適時stateを更新する。
import MicroContainer from 'react-micro-container';
import Counter from '../components/counter';
export default class CounterContainer extends MicroContainer {
constructor(props) {
super(props);
this.state = { count: 0 };
}
componentDidMount() {
this.subscribe({
increment: this.handleIncrement,
decrement: this.handleDecrement,
});
}
handleIncrement(count) {
this.setState({ count: this.state.count + count });
}
handleDecrement(count) {
this.setState({ count: this.state.count - count });
}
render() {
return <Counter dispatch={this.dispatch} {...this.state} />;
}
}
このコンポーネントも単なるReact Componentなのでこのコンテナを普通にマウントするだけ。
import ReactDOM from 'react-dom';
import CounterContainer from './container/counter';
ReactDOM.render(<CounterContainer />, document.getElementById('app'));
Ajaxしたり何なりも全部コンテナでやる。汚い部分を全部コンテナが引き受けることでコンポーネントの世界をきれいに保つことができる。そして覚えるのはdispatch
とsubscribe
だけで、あとは普通にReact使うのと変わらないというのが利点。
大きくなったらFlux的なの使おう。
実際に使ってみたか
Adventarをこれで書き換えてみた。オレオレFlux的な感じでやってたけど、そんなにコード量多くないのでこれで書き換えてだいぶすっきりした。