🧊

MobX 6.0.0 について

出ました。

mobx/CHANGELOG.md at mobx6 · mobxjs/mobx · GitHub

目玉機能!みたいなのはないです。
それだけ安定してるという意味でもある。

decorate() から makeObservable() へ

APIにおける一番の変更がコレ。

v4とv5では、いわゆるStoreはこんな風に作ってた。

import { decorate, observable } from 'mobx';

class FooStore {
  foo = 'text';
  shallowObj = {};
  shallowArr = [];
}

decorate(FooStore, {
  foo: observable,
  shallowObj: observable.shallow,
  shallowArr: observable.shallow,
});

`class`を作ったあとで、`decorate()`という関数でもってObservableにする。

この`decorate()`が廃止されて、代わりに`makeObservable()`と`makeAutoObservable()`という関数に。

import { makeObservable, observable } from 'mobx';

class FooStore {
  foo = 'text';
  shallowObj = {};
  shallowArr = [];

  constructor() {
    makeObservable(this, {
      foo: observable,
      shallowObj: observable.shallow,
      shallowArr: observable.shallow, 
    });
  }
}

まあそのまんまですね。

`observable.shallow`とか、`observable.ref`とかを使わないなら、`makeAutoObservable(this)`だけでもよいです。

`computed`や`action`なども、全部自分で明示するなら`makeObservable()`で。

TypeScriptの場合はこうしないと型エラーになるので注意。

import { makeObservable, observable } from 'mobx';

class FooStore {
  foo = 'text';
  shallowObj = {};
  shallowArr = [];

  constructor() {
    makeObservable<FooStore>(this, {
      foo: observable,
      shallowObj: observable.shallow,
      shallowArr: observable.shallow, 
    });
  }
}

ドキュメントが一新された

正直いままでのドキュメントは、お世辞にもわかりやすいとは言えませんでした。

新規でMobXに興味をもった人も、離脱するんじゃねーかってくらいに・・。

しかしそれも!今回で!!

About MobX · MobX

というわけで、めちゃくちゃ読みやすくなったので、ぜひ読んでください。

MobX x React

MobXユーザーはだいたいReactユーザーだと思うので、そっちも触れておく。

古いコードベースじゃない限りは、`mobx-react`ではなく、`mobx-react-lite`というパッケージを使ってください。

React integration · MobX

で、今回のアップデートではAPIの追加というよりも、DepricatedになったAPIのほうが多いです。

なんならこのパッケージからは4つのAPIしか利用を推奨しません。

  • `observer()` HoC
  • `Observer` コンポーネント
  • `useLocalObservable()` フック
  • `enableStaticRendering()`

これだけ。

コンポーネントで使う

コンポーネントをReactiveにするための方法が、いままでは3つあったんですが、それが2つになります。

この2つのどっちかを使う。

前者は、Functionコンポーネントに対してのみ使えて、後者はどちらの中でも使えます。(正確には、`mobx-react`パッケージの`observer()`は、Classコンポーネントにも使えるけど)

個人的には、HoCより、再描画させたい範囲を明示的に区切るために`Observer`を使いたい派です。

コンポーネント内で、Observableな値をつくる

`useState()`があるのでそこまで活躍の機会はないけど。

直接`mobx`パッケージから`observable()`を持ってきてもいいけど、フックでそれを定義できるというのが`useLocalObservable()`です。

ドキュメントにも書いてあるけど、ただのショートハンド。

const [state] = useState(() => observable(initializer(), annotations, { autoBind: true }))

SSR

最後に`enableStaticRendering()`について。

SSR環境では、Reactiveなコンポーネントも意味をなさないので、何もしなくていいですを伝えるためのAPIです。

いままでは`useStaticRendering()`って名前だったせいで、フックと勘違いされてESLintに怒られるっていうトラップがあった・・w