小さいReactアプリケーションのためのライブラリ書いた

  • 307
    Like
  • 0
    Comment
More than 1 year has passed since last update.

EventEmitterバケツリレースタイル/フレームワークなしで小さくFluxする - Qiita

これ見て最近は大体自分も同じような感じのことをしているので共通化できる最小限のコードをライブラリにしてみた。

https://github.com/hokaccha/react-micro-container

元記事でも言ってるようにやることはとても少ないのでライブラリ使わないでもいいんだけどそのへんは好み。

Usage

まず普通のステートレスなReactコンポーネントを作る。dispatchというpropsを受け取ってそれを通してイベントを発火するというのが唯一の規約。

components/counter.js
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を更新する。

container/counter.js
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なのでこのコンテナを普通にマウントするだけ。

app.js
import ReactDOM from 'react-dom';
import CounterContainer from './container/counter';

ReactDOM.render(<CounterContainer />, document.getElementById('app'));

Ajaxしたり何なりも全部コンテナでやる。汚い部分を全部コンテナが引き受けることでコンポーネントの世界をきれいに保つことができる。そして覚えるのはdispatchsubscribeだけで、あとは普通にReact使うのと変わらないというのが利点。

大きくなったらFlux的なの使おう。

実際に使ってみたか

Adventarをこれで書き換えてみた。オレオレFlux的な感じでやってたけど、そんなにコード量多くないのでこれで書き換えてだいぶすっきりした。