Recoil 0.0.10リリース!バグが修正されて、新機能も追加!

2020年6月18日にRecoi最新版となるバージョン0.0.10がリリースされました。バージョン0.0.9も同日にリリースされましたが、新機能のRecoil SnapshotのHooksのメソッド名が変更されて、すぐに0.0.10としてリリースされました。これによりNext.jsのようなSSR(サーバサイドレンダリング)をするようなフレームワークで発生していた下記の不具合も無事に修正されました。

SSR時にRecoil version 0.0.8だとwindow is not definedのエラーになる

さらにRecoil SnapshotsやTypeScriptのサポートなども追加されて、さらに用途の幅が広がりました。 詳細はこちらになります。

Recoil バージョン 0.0.10の内容

不具合修正

  • サーバサイドレンダリングに関する機能を修正。ただし、現時点では正式にはサポートしない。
  • 特定のケースでSelectorが dependency subscriptionsを記録することを修正。
  • 現時点のStateを取得するようにUpdaterを修正。
  • オープンソースのビルドの際、特定のエラーを投げる時のエラーメッセージを修正。
  • オープンソースのビルドの際、Flowエラーを減少。

改善

  • ほとんどのRecoil hooksでatomやselectorを使用していない場合に、意味の分かるメッセージでエラーを投げる。
  • テストの改善。
  • オープンソースのビルドの改善。

TypeScriptのサポート

  • APIとの同期を維持しやすくするために、DefinitelyTypedを使う代わりに、Recoil GitHubのリポジトリに置かれます。
  • @Typeは下記のようにしてインストールできます。これで型定義を個人で管理する必要はなくなります。
npm install @types/recoil
# or
yarn add @types/recoil

Recoil Snapshot機能!

Recoil SnapshotはRecoilのatomのStateのイミュータブル(不変の)スナップショットです。これはグローバルなRecoilのStateやその派生するStateを観察、検査そして管理するためのAPIを標準化することを意図しています。開発ツールやグローバルな状態の動機、履歴機能、ナビゲーション機能の実装に役に立ちます。

Hooks

RecoilではSnapshotと機能する4つのHooksがあります。

  • useRecoilSnapshot() - Snapshotへの同期アクセス
  • useRecoilCallback() - Snapshotへの非同期アクセス
  • useRecoilTransactionObserver() - 全てのStateの更新によるSnapshotをサブスクライブ
  • useGotoRecoilSnapshot() - Snapshotに一致する現在のStateの更新

詳細はこちらになります。

動作確認

いくつかの実装例はGitHub上に上がっています。

次の実装は値の変化を捉えるためだけの簡単なコードです。

import React from "react";
import {
  atom,
  useRecoilState,
  useRecoilTransactionObserver_UNSTABLE,
  Snapshot,
  useRecoilSnapshot,
} from "recoil";

const testState = atom({key: 'test', default: 0});

export const Test = () => {
  const [test, setSet] = useRecoilState(languageState);
  const currentSnapshot = useRecoilSnapshot();
  // Store history data
  const [history, setHistory] = React.useState({
    past: [],
    present: currentSnapshot,
  });
  // Get current value
  console.log("currentSnapshot loadable", currentSnapshot.getLoadable(testState));
  // If you need to use async, do as following.
  // console.log(" + promise", currentSnapshot.getPromise(testState));
  useRecoilTransactionObserver_UNSTABLE(({ snapshot, previousSnapshot }) => {
    console.log("transaction current getLoadable", snapshot.getLoadable(testState));
    //console.log(" + getPromise", snapshot.getPromise(languageState));
    setHistory({
      past: [...history.past, previousSnapshot],
      present: snapshot,
    });
  });
  
  return (
    <div>
          <p>{test}</p>
    	  <button onClick={()=>setTest(test+1)}>increase</button>
    </div>
  )
}

画面が表示されると、コンソールに現在の値が出ます。 getLoadableで現在の値を同期的に取得できます。非同期の際は、getPromiseを使います。 結果はこのようになります。

currentSnapshot loadable {state: "hasValue", contents: "0", getValue: ƒ, toPromise: ƒ, valueMaybe: ƒ, ...}

画面でincreaseボタンを押すたびに、useRecoilTransactionObserver_UNSTABLEで変更がサブスクライブされているので、この中のコードが実行されます。 そこでも同じように現在の値とその前の値が取得できます。 これを例のようにhistoryとして管理しておくこともできます。

重要

Snapshotはグローバルです。使うときは注意しましょう。

まだまだできたばかりですし、unstableなコードもあるので、しばらくは様子見というのがよいでしょう。

Updated at: Thu Jun 25 2020

© 2020-presentTerms|Privacy