


いちおうContributorもやってるので、なにか質問等あれば、この後の懇親会でもTwitterとかでもお気軽に!
必要なものを自分で見て「選択」する力を試すということで・・(˘ω˘ )
state)を管理するためのライブラリ3.1.16Reactと相性がよいのであわせて使われることが多いけど、別に依存関係はないです。
海外では既にそれなりに、日本でも少しずつ認知されてきた感がある今日このごろ。

ActionsによりStateを変更する。
Stateが変更されると、自動的にReactionsが発火する。(= Viewsも更新される。view = f(state))

mobx.actionmobx.observable, mobx.computedmobx.reaction, mobx.autorunmobx-react.observer他にもAPIは色々ありますが、最低限これだけ覚えれば十分です。
const { autorun, observable } = require('mobx');
// State
const state = observable({
count: 1,
});
// Reaction(Views)
autorun(() => {
console.log(`Count is ${state.count}!`); // Count is 1!
});
// Actions
function increment() { state.count++; }
function decrement() { state.count--; }
increment(); // Count is 2!
increment(); // Count is 3!
decrement(); // Count is 2!
Stateを定義して、使用して、変更するだけ。これが全て。
Stateが変更されると自動的にただのオブジェクトで管理するよりも圧倒的にわかりやすいです。
const { action, computed, observable } = require('mobx');
// ObservableなStateと、Stateを変更するAction
// Decoratorsは必須ではなくOptionalな選択肢
class Store {
@observable count = 1;
// ObservableなStateに更新があった時"だけ"、自動的に更新されるプロパティ
@computed get isOdd() {
return !!(this.count % 2);
}
@action increment() {
this.count++;
}
@action decrement() {
this.count--;
}
}
// ViewからStoreのActionを呼ぶための・View以外の用途にStoreを使う層
// 別にViewから直接Storeを叩いてもいいけど
function createEvent(store) {
return {
increment() {
store.increment();
},
decrement() {
store.decrement();
}
};
}
const React, { Component } = require('react');
const { observer } = require('mobx-react');
// ObservableなStateに更新があった時"だけ"、自動的にrenderされるコンポーネント
@observer
class View extends Component {
render() {
const { store, event } = this.props;
return (
<div>
<div>{store.count}</div>
<button onClick={event.increment}>+</button>
<button onClick={event.decrement}>-</button>
</div>
);
}
}
const ReactDOM = require('react-dom');
const { useStrict, reaction } = require('mobx');
// @acitonからしかStateが変更できないように
useStrict(true);
const store = new Store();
// Stateの用途1
// ObservableなStateに更新があった時"だけ"、自動的に呼ばれる関数
reaction(
() => store.isOdd,
isOdd => {
console.log(isOdd ? 'odd' : 'even');
}
);
// Stateの用途2
ReactDOM.render(
<View store={store} event={createEvent(store)} />,
document.getElementById('app')
);
MobX自身はアーキテクチャは規定しないので、Fluxぽくするもよし、MVCぽくするもよし、MVVMぽくするもよし。
Stateをどう定義するかが最大の関心事になるStateを用途に応じてリンクさせていくStateを更新すれば、「変更が必要なものだけ」が自動的にアップデートされるshouldComponentUpdate的なチューニングも不要になるつまりStateを更新するだけで、
そんな思想を体現したDEMOのご紹介。
トーク自体もおもしろいのでおすすめです。
やや作者のクセが感じられると個人的には思ってたりする・・(˘ω˘ )
ReactDOM.render()をソースから消してみた状態でも動く// Viewですら副作用であり必須ではない
shop.cart.checkout()
shop.cart.clear()
// URLでさえも
shop.view.openCartPage()
shop.view.openBooksPage()
// 全ての機能が動く
shop.books.keys()
shop.cart.addBook(shop.books.get('978-1423103349'))
shop.cart.addBook(shop.books.get('978-1423103349'), 2, false)
shop.cart.checkout()
https://github.com/mweststrate/react-mobx-shop/blob/react-amsterdam-2017/src/index.js#L13-L40
Stateの更新によって反映されるべきものを紐付けReactを使った画面表示Stateを更新すればすべて自動で反映Storeを用意してまとめるBackboneのModelとCollectionの関係のようなhttps://github.com/mweststrate/react-mobx-shop/blob/react-amsterdam-2017/src/stores/ViewStore.js
https://github.com/mweststrate/react-mobx-shop/blob/react-amsterdam-2017/src/index.js#L17-L22 https://github.com/mweststrate/react-mobx-shop/blob/react-amsterdam-2017/src/components/Books.js#L4
ProviderでContextに注入してinject()で取り出せるobserver()は、そのコンポーネントが使用している値に更新があった時のみrender()してくれるこの2つの仕組みを備えたライブラリです。
ちゃんと自分の目で見て試して「選択」してください・・・!
需要があれば、またの機会にどこかで!