BattleProgrammerShibata

ある日は誰かと戦い、ある日は何かと戦い、そしてある日は自分と戦うのだろう、そういう生き物。

状態管理ライブラリ MobX の具合を知りたかったので TypeScript で React と組み合わせてシンプルな Timer を書いた

MobX なるものに興味を持ったので、動きを掴むために。

MobX は、曰く「簡潔でスケーラブルな状態管理イブラリ」。
少し調べてみたところ、まだまだ国内での情報は少ない様子。

github.com

MobX による状態管理が一体どういう具合なのか知りたかったので、実際に書いてみることにした。

言語には TypeScript を用い、React と組み合わせて書いた。

github.com

React と組み合わせる場合には mobxjs/mobx-react が必要になるので、これを利用している。
機能は「ページ表示からの秒数をカウントし、ボタンが押されたらリセットする」という簡単な Timer 機能。

実際に動いているデモはこれ。

f:id:bps_tomoya:20170609235533g:plain

https://tomoyashibata.github.io/react-mobx-typescript-timer-sample/

まったく量はないけれど、コアな部分について以下説明。

Store

// TimerStores.ts
import { observable } from 'mobx'

export class TimerStore {
  @observable timer = 0

  constructor() {
    setInterval(() => {
      this.timer += 1
    }, 1000)
  }

  resetTimer() {
    this.timer = 0
  }
}

Store クラスは状態を持ち、またその状態を変化させる役割をもつ。
見ての通り、プロパティ timer には @observable というデコレータを付与した。 これが MobX の機能の1つで、これにより timer は「観測可能」なプロパティになる。

React View

// TimerView.tsx
import * as React from 'react'
import { observer } from 'mobx-react'
import { TimerStore } from '../stores/TimerStores'

@observer
export class TimerView extends React.Component<{ timerStore: TimerStore }, {}> {
  onReset = () => this.props.timerStore.resetTimer()

  render() {
    return (
      <div>
        <button onClick={this.onReset}>
          Seconds passed: {this.props.timerStore.timer}
        </button>
      </div>
    )
  }
}

今度は mobx-react の機能を用いて React View の Class に @observer というデコレータが付与されている。 さきほどの TimerStore@observable を付与したプロパティの「購読」をすることができる。
こうすることで timer が更新されると、その状態は自動的に反映、描画される。また、ボタンがクリックされた場合には Store で定義したリセットの処理を呼び出すようにしている。

これで、MobX による状態管理を用いた「ページ表示からの秒数をカウントし、ボタンが押されたらリセットする」が実現できる。