react-dispatcher-decorator というのを作った
npm install react-dispatcher-decorator --save
コンセプト
昔作ったArdaのPubSub部分をDecoratorで表現した。https://github.com/mizchi/arda
この2つを使ってバケツリレーを隠蔽することで、デコレータでPub側とSub側を自然に繋げられるようにした。
hokaccha/react-micro-container: Micro framework for React も多少参考にした。
Example
import React from "react";
import {dispatcher, subscriber} from "react-dispatcher-decorator";
// This component subscribes events from child components by context
@subscriber((self, subscribe) => {
subscribe('foo', (prop) => {
console.log('foo received with', prop);
});
})
class App extends React.Component {
render() {
return <Child/>
}
}
// This component has this.context.dispatch and it will dispatch to parent subscriber
@dispatcher
class Child extends React.Component {
render() {
return <button onClick={() => this.context.dispatch('foo', 1)}>hello</button>
}
}
import ReactDOM from "react-dom";
const el = document.querySelector(".main");
ReactDOM.render(<App/>, el);
Pub側で@subscriber
デコレータを宣言しながらエミッターを初期化する。意図的に動的には生やしたりはできないようにしている。
@dipatcher
が付与されたComponentの this.context.dispatch
は自分の@subscribe
デコレータを持つ親(何層上でもおk)のsubscribe
を発火させる。
with PromisedReducer
これも自作のライブラリだけど、
を使うと、こんな感じになる。
import React from "react";
import {dispatcher, subscriber} from "react-dispatcher-decorator";
import PromisedReducer from "promised-ruducer";
@subscriber((self, subscribe) => {
const reducer = new PromisedReducer({count: 0});
reducer.on(":update", state => self.setState(state));
subscribe('increment', (prop) => {
reducer.update(state => ({count: state.count + 1}));
});
})
class App extends React.Component {
render() {
return <Child count={this.state.count}/>
}
}
// This component has this.context.dispatch and it will dispatch to parent subscriber
@dispatcher
class Child extends React.Component {
render() {
return <button onClick={() => this.context.dispatch('increment')}> {this.props.count} </button>
}
}
// 略
PromisedReducer はこれまた自分が作った https://github.com/mizchi/flumpt の非同期更新のバッチ処理を最適化する部分を抜き出したもので、要はこの例はFlumptを小さいパーツに分解してデコレータ構文に糖衣して再構築するとこうなる、というもの。
flumpt はSSR対応してなかったんだけど、仕組み上だるかったので、SSRしたいならこういうアプローチでいけるはず。