ReactEurope 2017のDay2より。
動画とスライドのリンクはこちらから。
MobXのサブプロジェクトみたいな存在である`mobx-state-tree`についてのトークです。
`mobx-state-tree`とは
本編はもちろんMobXについては知ってる前提 + `mobx-state-tree`のREADMEくらいは眺めてふんふんって感じじゃないと辛いかも・・って感じなので、さくっと紹介。
GitHub - mobxjs/mobx-state-tree: Opinionated, transactional, MobX powered state container
MobXを使う場合、アーキテクチャは特に指定がない。
その分だけ柔軟で、ボイラープレート的なコードも不要で書き味が良い!っていうメリットがある反面、やっぱりスケールさせるならルールが必要でしょ!考えればいいっちゃ良いけど、なんかお手本的なコードとか仕組みとかあった方が嬉しいよねーっていうのもあり。
そこで作者のMichelが目下やってるプロジェクトがコレです。
本編メモ
MobX vs Redux
- この観点も悪くないが、いいとこどりできればより良い
- それぞれ表すなら
- Mutable Model Graph -> MobX
- Immutable Tree -> Redux
- どちらもメリットとデメリットがある
- そこでいいとこどりの`mobx-state-tree`!
- 以下、メインの機能の紹介
Snapshots
- 良いよねー
- Reduxだと、Stateのツリーがそのまま使える
- MobXだと、`computed`でそれ用の関数をModelに生やせばいい
- ただそれだとボイラープレートなコードがどうしても必要になる・・
- `mobx-state-tree`だと、`getSnapshot()` / `onSnapshot()` / `applySnapShot()`ってのが用意されてる
TypeChecks
- ランタイムの型チェックができるようになってる
- どのモデルがどういう型か
- エラーになったなら何をどうしようとしたかがわかる
そもそも、Modelの定義をこれでやる。
import { types } from "mobx-state-tree" const Todo = types.model("Todo", { title: types.string, done: false }, { toggle() { this.done = !this.done } }) const Store = types.model("Store", { todos: types.array(Todo) })
みたいな。
JSON patch
- http://jsonpatch.com/
- どういう処理がツリーに対して行われたか残る
- `add` / `replace` / 'remove'
- サーバーサイドから他の人の変更差分をもらって反映・・とか
Actions
- ダイレクトな値の更新を禁止する
- ツリーのどの部分に対してどういう変更をしたか残る
- 更新できるのは自身とそのサブツリーのみ
- Actionも記録されるのでリプレイもできる
- `clone()`したデータに対しても同じく
- `middleware`をかますこともできる
値の参照の問題
- Mutableだと次の行で参照先が変わってる可能性がある
- Immutableだとその心配はない
- これもSnapshotを使って解決できる
- モデルどうしの参照でも有用な概念
所感
- ImmutableとMutableの狭間でどう生きてくか・・は確かに課題感があったのでおもしろかった
- ただちょっとOpinionated過ぎるかなーという気もする
- MobXを完璧に把握してないと旨味を味わう前に挫折しそう
- てか、こういうのが必要 = Reduxでやれ案件な気もする
- MobXやる上でSnapshotのアイデアはすごくよい
- Model間での参照、連携問題は確かに悩んでた
- 個別に`toJS()`するのも面倒やなーと思ってた
- ちなみにReduxのインテグレーションあるんやでまじやで