🧊

mobx-reactとmobx-react-liteと、それぞれのobserver APIの違い

わかってる側からすると無意識に選んでたけど、わかってない側からすると混乱するよなこれ・・。

と思ったので、今さらではあるが言語化の意味も込めてメモ。

mobx-reactファミリー

MobXを使ってReactのコンポーネントをよしなに描画するためにはライブラリが必要。
で、それらはReactのバージョンによって、いくつか選択肢がある。

  • `mobx-react-lite`
  • `mobx-react@6`
  • `mobx-react@5`

選び方としては、

という感じ。

https://mobx-react.js.org/libraries

observer API

MobXで用意した値の変更に応じて、コンポーネントを再描画させるには、なんらかのobserver APIが必要。

という感じで、どれを使ったらいいんやってなりそうなので、それぞれの特徴について。

`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は複数あったらその順番とかあれこれハマりやすいパターンなので、最近はあまり歓迎されていないような印象もあり。

今あえて選ぶ理由はない気がする。

https://mobx-react.js.org/observer-hoc

`Observer`コンポーネント

export const Component = (props) => (
  <section>
    <h1>Counter</h1>
    <Observer>{() => (
      <p>Count: {props.count}</p>
    )}</Observer>
  </section>
);

というように、任意の場所を指定できるのが`observer()`との決定的な違い。

自身より上層(外側)のスコープで定義された値にしか追従しないので、ネストさせるときは注意。

その他は気にすべき点も特になく、いちばん馴染みやすい書き味だと思うので、とりあえずコレって感じでいいと思ってる。

https://mobx-react.js.org/observer-component

`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と組み合わせて使えるとも思えないので・・。

https://mobx-react.js.org/observer-hook