開発ツール
Recoil には、状態の変化を観察および更新するための機能があります。
重要な注意事項
この API は現在開発中で変更されます。続報をお待ちください...
すべての状態変化の観察
useRecoilSnapshot()
や useRecoilTransactionObserver_UNSTABLE()
などのフックを使用して状態の変化をサブスクライブし、新しい状態の Snapshot
を取得できます。
Snapshot
が入手できたら、getLoadable()
、getPromise()
、getInfo_UNSTABLE()
などのメソッドを使用して状態を調べ、getNodes_UNSTABLE()
を使用して既知の原子集合を反復処理できます。
function DebugObserver(): React.Node {
const snapshot = useRecoilSnapshot();
useEffect(() => {
console.debug('The following atoms were modified:');
for (const node of snapshot.getNodes_UNSTABLE({isModified: true})) {
console.debug(node.key, snapshot.getLoadable(node));
}
}, [snapshot]);
return null;
}
function MyApp() {
return (
<RecoilRoot>
<DebugObserver />
...
</RecoilRoot>
);
}
オンデマンド状態変更の観察
または、useRecoilCallback()
フックを使用してオンデマンドで Snapshot
を取得できます。
function DebugButton(): React.Node {
const onClick = useRecoilCallback(({snapshot}) => async () => {
console.debug('Atom values:');
for (const node of snapshot.getNodes_UNSTABLE()) {
const value = await snapshot.getPromise(node);
console.debug(node.key, value);
}
}, []);
return <button onClick={onClick}>Dump State</button>
}
タイムトラベル
useGotoRecoilSnapshot()
フックを使用して、指定した Snapshot
に一致するように Recoil 状態全体を更新できます。この例では、状態の変更履歴を保持し、前のグローバル状態に戻して復元する機能を提供しています。
Snapshot
には getID()
メソッドも用意されています。これはたとえば、スナップショットの履歴を更新しないように、以前の既知の状態に戻っているかどうかを判断するために使用できます。
function TimeTravelObserver() {
const [snapshots, setSnapshots] = useState([]);
const snapshot = useRecoilSnapshot();
useEffect(() => {
if (snapshots.every(s => s.getID() !== snapshot.getID())) {
setSnapshots([...snapshots, snapshot]);
}
}, [snapshot]);
const gotoSnapshot = useGotoRecoilSnapshot();
return (
<ol>
{snapshots.map((snapshot, i) => (
<li key={i}>
Snapshot {i}
<button onClick={() => gotoSnapshot(snapshot)}>
Restore
</button>
</li>
))}
</ol>
);
}
現在の状態の検査
useGetRecoilValueInfo_UNSTABLE()
は、現在の状態を覗き見して Atom とセレクターに関する情報を取得するために利用できるコールバックを提供します。たいていの場合、これは現在存在する Snapshot
で getInfo_UNSTABLE()
を呼び出すのと同じですが、Atom を購読している React コンポーネントのセットなどの追加情報を提供できるという違いがあります。これは変更される可能性があり、Recoil 状態のスナップショットに関連付けられません。