わかってる側からすると無意識に選んでたけど、わかってない側からすると混乱するよなこれ・・。
と思ったので、今さらではあるが言語化の意味も込めてメモ。
mobx-reactファミリー
MobXを使ってReactのコンポーネントをよしなに描画するためにはライブラリが必要。
で、それらはReactのバージョンによって、いくつか選択肢がある。
- `mobx-react-lite`
- `mobx-react@6`
- `mobx-react@5`
選び方としては、
- `react@16.8.0`以上で、Classコンポーネントは使わず、FunctionalコンポーネントとHooksベースで書いてる
- `mobx-react-lite`
- `react@16.8.0`以上だが、Classコンポーネントも使ってるし、Functionalコンポーネントも混在してる
- `mobx-react@6`
- それ以外
- `mobx-react@5`
という感じ。
observer API
MobXで用意した値の変更に応じて、コンポーネントを再描画させるには、なんらかのobserver APIが必要。
- `mobx-react@5`
- `observer`HOC
- `Observer`コンポーネント
- `mobx-react@6`
- `observer` HOC
- `Observer`コンポーネント
- `mobx-react-lite`
- `observer`HOC
- `Observer`コンポーネント
- `useObserver`フック
という感じで、どれを使ったらいいんやってなりそうなので、それぞれの特徴について。
`observer`HOC
コンポーネントを`observer()`でラップするスタイル。
export const FunctionalComponent = (props) => <p>Count: {props.count}</p>; export const Component = observer(FunctionalComponent);
今となっては懐かしい高階関数パターン。
`mobx-react`の場合は、ClassコンポーネントでもFunctionalコンポーネントでも渡せるけど、`mobx-react-lite`の場合は、Functionalコンポーネントしか渡せない。
HOCは複数あったらその順番とかあれこれハマりやすいパターンなので、最近はあまり歓迎されていないような印象もあり。
今あえて選ぶ理由はない気がする。
`Observer`コンポーネント
export const Component = (props) => ( <section> <h1>Counter</h1> <Observer>{() => ( <p>Count: {props.count}</p> )}</Observer> </section> );
というように、任意の場所を指定できるのが`observer()`との決定的な違い。
自身より上層(外側)のスコープで定義された値にしか追従しないので、ネストさせるときは注意。
その他は気にすべき点も特になく、いちばん馴染みやすい書き味だと思うので、とりあえずコレって感じでいいと思ってる。
`useObserver`フック
export const Component = (props) => { return useObserver(() => ( <section> <h1>Counter</h1> <p>Count: {props.count}</p> </section> )); };
という感じでいちばんローレベルな実装。
`mobx-react-lite`では、`observer`HOCも`Observer`コンポーネントも、内部的にはこれを呼んでる。
自由度は高い分、これの存在意義とは・・・?ってなるうちは、使う必要ないと思う。
Hooksとは言ってるけど、他のHooksと組み合わせて使えるとも思えないので・・。