Loadable
Recoil state の状態を表すためのインターフェース
Loadable の状態を表す state と、値を格納するための contents という2つのプロパティを持っている
Loadable は次の3つのいずれかの状態を持つ
pending: まだ value が確定していない状態
contents には value の Promise が格納されている
hasValue: value が確定した状態
contents には value が格納されている
hasError: 非同期処理がエラーで終了した状態
contents には Error が格納されている
https://gyazo.com/408e146797819b2c77f4beae6d5af405
図が間違っていたので修正
reset() は pending に戻すのではなく、最初に確定した hasValue の時の value に戻す操作であることに注意
本質的に set() とあまり変わらないので、この図には載せなかった
Promise と比較すると分かりやすいかも知れない
非同期の値を表現するためのインターフェースという意味で、 Promise と Loadable はよく似ている
どちらも非同期を3つの状態で表現する
どちらも Immutable として扱われる
厳密にいうと Promise は「内部状態は変化するが観測できない」だけなので read-only Mutable とでも呼ぶべき?
Loadable が Promise と決定的に違うのは、値 (状態) に "同期的に" アクセスできるという点である
Promise は値 (状態) をカプセル化している、クローズなインターフェースである
Loadable は値 (状態) を プロパティとして露出している、オープンなインターフェースである
Loadable は Promise のスナップショットである、と考えれば分かりやすいかも知れない teramotodaiki.icon
render 関数の中で value にアクセスすることの多い React (Recoil) では、素の Promise では都合が悪いのだと思う
そこで Recoil は、Promise を拡張して、React と相性の良い Loadable というインターフェースを作った
正直、これだけでも大きな発明だと思う。Redux にも応用できるのではないか?teramotodaiki.icon Promise と Loadable はどちらも read-only だが、 read-only を実現するアプローチが異なる
Promise には value にアクセスするプロパティがない
value を得る唯一の方法は then で新しい Promise を作ること
Loadable は作成時に Object.freeze() されているので、書き込みが行われた場合 TypeError を発生させる
Promise の then に相当する map というメソッドで、新しい Loadable を作ることもできる