useRecoilCallback(callback, deps)
このフックはuseCallback()
と似ていますが、コールバックがRecoilの状態を操作するためのAPIも提供します。このフックは、Recoilの状態の読み取り専用Snapshot
にアクセスでき、非同期で現在のRecoilの状態を更新する機能を持つコールバックを構築するために使用できます。
このフックを使用する動機には、以下のようなものがあります。
- 原子またはセレクターが更新された場合に、Reactコンポーネントを再レンダリングするためにサブスクライブすることなく、非同期でRecoilの状態を読み取る。
- レンダリング時に実行したくない、コストのかかるルックアップを非同期アクションに遅延させる。
- Recoilの状態の読み書きも行いたい副作用を実行する。
- どの原子またはセレクターを更新したいかをレンダリング時に判断できない可能性があるため、
useSetRecoilState()
を使用できない場合に、原子またはセレクターを動的に更新する。 - プリフェッチデータをレンダリングする前に。
type CallbackInterface = {
snapshot: Snapshot,
gotoSnapshot: Snapshot => void,
set: <T>(RecoilState<T>, (T => T) | T) => void,
reset: <T>(RecoilState<T>) => void,
refresh: <T>(RecoilValue<T>) => void,
transact_UNSTABLE: ((TransactionInterface) => void) => void,
};
function useRecoilCallback<Args, ReturnValue>(
callback: CallbackInterface => (...Args) => ReturnValue,
deps?: $ReadOnlyArray<mixed>,
): (...Args) => ReturnValue
callback
- コールバックインターフェースを提供するラッパー関数付きのユーザーコールバック関数。状態を変更するコールバックは、現在のRecoilの状態を非同期で更新するためにキューに入れられます。ラップされた関数の型シグネチャは、返されるコールバックの型シグネチャと一致します。deps
- コールバックをメモ化するためのオプションの依存関係のセット。useCallback()
と同様に、生成されたコールバックはデフォルトではメモ化されず、レンダリングごとに新しい関数が生成されます。空の配列を渡すと、常に同じ関数インスタンスが返されます。deps
配列に値を渡すと、いずれかの依存関係の参照の等価性が変更された場合に新しい関数が使用されます。これらの値は、コールバックの本文内から、古くなることなく使用できます。(参照:useCallback
) eslintを更新して、これが正しく使用されていることを確認できます。
コールバックインターフェース
snapshot
-Snapshot
は、スナップショットにアクセスしたときのRecoil原子の状態の読み取り専用のビューを提供します。原子の値は静的ですが、非同期セレクターは引き続き解決する可能性があります。スナップショットは、同期または非同期のコールバックの間保持されますが、その範囲を超えて保存および使用する場合は、明示的に保持する必要があります。gotoSnapshot
- グローバル状態を更新して、提供されたSnapshot
と一致させるようにキューに入れます。set
- 原子またはセレクターの値を設定するためにキューに入れます。他の場所と同様に、新しい値を直接提供するか、新しい値を返し、現在の値をパラメータとして取るアップデーター関数を提供できます。現在の値は、現在のトランザクションでのこれまでの他のすべてのキューに入れられた状態の変更を表します。reset
- 原子またはセレクターの値をデフォルトにリセットします。refresh
- セレクターキャッシュを更新します。transact_UNSTABLE
- トランザクションを実行します。useRecoilTransaction_UNSTABLE()
のドキュメントを参照してください。
注意: コールバックインターフェースは、オーバーヘッドを避けるための最適化として、オンデマンドでプロパティを遅延的に計算する場合があります。このため、コールバックインターフェースをスプレッド演算子を使用して渡すのではなく、明示的にプロパティを逆参照するか、プロキシオブジェクト全体を渡す必要があります。
遅延読み込みの例
この例では、useRecoilCallback()
を使用して、状態が変更されたときにコンポーネントを再レンダリングするためにサブスクライブすることなく、遅延的に状態を読み取ります。
import {atom, useRecoilCallback} from 'recoil';
const itemsInCart = atom({
key: 'itemsInCart',
default: 0,
});
function CartInfoDebug() {
const logCartItems = useRecoilCallback(({snapshot}) => async () => {
const numItemsInCart = await snapshot.getPromise(itemsInCart);
console.log('Items in cart: ', numItemsInCart);
}, []);
return (
<div>
<button onClick={logCartItems}>Log Cart Items</button>
</div>
);
}