Recoil公式ドキュメント 翻訳㉖ APIリファレンス-Core-useRecoilCallback()

Recoilの公式ドキュメントをgoogle翻訳するとコードまで翻訳されてしまうのが面倒なのでQiitaにまとめてみます。

追々追加していきます。(多分)

[公式ドキュメント](https://recoiljs.org/docs/api-reference/core/useRecoilCallback)

## 目次

* **前書き**　[①](https://qiita.com/Daichi44/items/4236857dac4a3365f434)　[②](https://qiita.com/Daichi44/items/f6f8995a73387d104777)　[③](https://qiita.com/Daichi44/items/b46d9659c8fcfad2c227)　[④](https://qiita.com/Daichi44/items/3356aaeb7a387b520621)
* **基本チュートリアル**　[⑤](https://qiita.com/Daichi44/items/ee1ced6040d06e33e165)　[⑥](https://qiita.com/Daichi44/items/d6c2472043b473c9819d)　[⑦](https://qiita.com/Daichi44/items/af3d6363ac3ce3e7af5a)
* **ガイド**　[⑧](https://qiita.com/Daichi44/items/47e9ac34c61c35531abb)　[⑨](https://qiita.com/Daichi44/items/ae631b34ac50fb9bbd1d)　[⑩](https://qiita.com/Daichi44/items/45093185eb06fb4e1171)
* **APIリファレンス**
 * **Core** <br>
   •　[⑪ \<RecoilRoot /\>](https://qiita.com/Daichi44/items/b440f33d3831b86c62b9) <br>
   •　**State**　[⑫](https://qiita.com/Daichi44/items/0a9b9af69dddddbcd7e2)　[⑬](https://qiita.com/Daichi44/items/13912706763c22f9cbe9)　[⑭](https://qiita.com/Daichi44/items/812aa5ebf149c849e108)　[⑮](https://qiita.com/Daichi44/items/2ec591ec3e952f1784c3)　[⑯](https://qiita.com/Daichi44/items/f78a2ce0cfc01de354c5)　[⑰](https://qiita.com/Daichi44/items/ab0e98e0a48d0a59bdb4)　[⑱](https://qiita.com/Daichi44/items/a887cfa33260136b1d68)　[⑲](https://qiita.com/Daichi44/items/679030df40e81a608be5)　[⑳](https://qiita.com/Daichi44/items/f682baf85f0e2673abfc)　[㉑](https://qiita.com/Daichi44/items/1c38716dc0738da3bc02) <br>
   •　**Snapshots**　[㉒](https://qiita.com/Daichi44/items/84a7218e76f62d41d0b7)　[㉓](https://qiita.com/Daichi44/items/de7e39f80cd1fdce8b7c)　[㉔](https://qiita.com/Daichi44/items/eda197468b0204349d5f)　[㉕](https://qiita.com/Daichi44/items/0bbe5d6643462b55df11) <br>
   •　<font color="orange">**㉖ useRecoilCallback()**</font> <br>
   •　**雑録(Misc)**　[㉗](https://qiita.com/Daichi44/items/78292a5c30b1b1e4813f) <br>
 * **実用(utils)**　[㉘](https://qiita.com/Daichi44/items/c6046e45ba7447a64aed)　[㉙](https://qiita.com/Daichi44/items/f552dfda4765596d83d7)　[㉚](https://qiita.com/Daichi44/items/7e568ccfb6d2e504de13)　[㉛](https://qiita.com/Daichi44/items/6973c6d140b697b2c97e)　[㉜](https://qiita.com/Daichi44/items/b929ff5376d0672dafa0)　[㉝](https://qiita.com/Daichi44/items/e9720f6ceb7cea57b2ce)　[㉞](https://qiita.com/Daichi44/items/c9bb722022a003d72aa9)　[㉟](https://qiita.com/Daichi44/items/ca11fcef04d764ef13a8)



※[全目次](https://qiita.com/Daichi44/items/0a276eb144f443a72efd#%E5%85%A8%E7%9B%AE%E6%AC%A1)は一番下にあります

***

# useRecoilCallback(callback, deps)

​このhookは[`useCallback()`](https://reactjs.org/docs/hooks-reference.html#usecallback)に似ていますが、コールバックがRecoil stateで動作するためのAPIも提供します。​
このhookを使用すると、Recoil stateの読み取り専用の[`Snapshot`](https://qiita.com/Daichi44/items/84a7218e76f62d41d0b7)へのアクセス権と、現在のRecoil stateを非同期に更新する機能を持つコールバックを構築できます。

​このhookを使用する動機には、次のようなものがあります。

* atomまたはselectorが更新された場合、Reactコンポーネントを登録せずにRecoil stateを非同期に読み取り、再描画します。
* ​レンダリング時に実行したくない非同期アクションに対して高価な検索を延期します。
* Recoil stateへの読み取りまたは書き込みを行う場合に、副作用を実行します。
* レンダリング時に更新するatom、またはselectorがわからない可能性があるatom、またはselectorを動的に更新するため、[`useSetRecoilState()`](https://qiita.com/Daichi44/items/ab0e98e0a48d0a59bdb4)を使用できません。
* レンダリング前にデータを[プリフェッチ](https://qiita.com/Daichi44/items/47e9ac34c61c35531abb#%E3%83%97%E3%83%AA%E3%83%95%E3%82%A7%E3%83%83%E3%83%81)しています。

***

```React
type CallbackInterface = {
  snapshot: Snapshot,
  gotoSnapshot: Snapshot => void,
  set: <T>(RecoilState<T>, (T => T) | T) => void,
  reset: <T>(RecoilState<T>) => void,
};

function useRecoilCallback<Args, ReturnValue>(
  callback: CallbackInterface => (...Args) => ReturnValue,
  deps?: $ReadOnlyArray<mixed>,
): (...Args) => ReturnValue
```

* `​callback` - コールバックインターフェースを提供するラッパー関数を持つユーザーコールバック関数。​stateを変更するコールバックはキューに入れられ、現在のRecoil stateを非同期に更新します。​ラップされた関数の型[シグネチャ](http://e-words.jp/w/%E3%82%B7%E3%82%B0%E3%83%8D%E3%83%81%E3%83%A3.html)は、返されたコールバックの型[シグネチャ](http://e-words.jp/w/%E3%82%B7%E3%82%B0%E3%83%8D%E3%83%81%E3%83%A3.html)と一致します。
* `deps` - コールバックを記憶するための、オプションの依存関係のセット。​`useCallback()`と同様に、生成されたコールバックはデフォルトでは記憶されず、レンダーのたびに新しい関数が生成されます。​空の配列を渡すと、常に同じ関数[インスタンス](http://e-words.jp/w/%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9.html)を返すことができます。​deps配列に値を渡すと、depの参照の等価性が変更された場合に新しい関数が使用されます。​これらの値は、コールバックの本体内から、古くならずに使用できます。​([`useCallback`](https://reactjs.org/docs/hooks-reference.html#usecallback)を参照) [eslintを更新](https://recoiljs.org/docs/introduction/installation#eslint)して、これが正しく使用されるようにすることができます。

コールバックインターフェース:

* `snapshot` - [`Snapshot`](https://qiita.com/Daichi44/items/84a7218e76f62d41d0b7)は、コールバックが呼び出された現在の[トランザクション](http://e-words.jp/w/%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B6%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3.html)が開始されたときにReactバッチでコミットされたRecoil atomのstateを読み取り専用で表示します。​atomの値は静的ですが、非同期selectorはまだ保留中または解決中の可能性があります。
* `gotoSnapshot` - 指定された[`Snapshot`](https://qiita.com/Daichi44/items/84a7218e76f62d41d0b7)に一致するようにグローバルstateを更新する[エンキュー](http://e-words.jp/w/%E3%82%AD%E3%83%A5%E3%83%BC.html#Section_%E3%82%A8%E3%83%B3%E3%82%AD%E3%83%A5%E3%83%BC/%E3%83%87%E3%82%AD%E3%83%A5%E3%83%BC)を行います。
* `set` - atomまたはselectorの値を設定する[エンキュー](http://e-words.jp/w/%E3%82%AD%E3%83%A5%E3%83%BC.html#Section_%E3%82%A8%E3%83%B3%E3%82%AD%E3%83%A5%E3%83%BC/%E3%83%87%E3%82%AD%E3%83%A5%E3%83%BC)。​他の場所と同様に、新しい値を直接指定することも、新しい値を返し、現在の値をパラメータとして受け取る更新関数を指定することもできます。​現在の値は、現在の[トランザクション](http://e-words.jp/w/%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B6%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3.html)内の他のすべての[エンキュー](http://e-words.jp/w/%E3%82%AD%E3%83%A5%E3%83%BC.html#Section_%E3%82%A8%E3%83%B3%E3%82%AD%E3%83%A5%E3%83%BC/%E3%83%87%E3%82%AD%E3%83%A5%E3%83%BC)されたstateの変更を表します。
* `reset` - atomまたはselectorの値を既定値にリセットします。

## ​遅延読み取りの例

​この例では、**`useRecoilCallback()`**を使用して、stateが変化したときに再レンダリングするコンポーネントを登録せずに、stateを遅延読み込みします。

```React
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>
  );
}
```

***

### 参考サイト
・[公式ドキュメント](https://recoiljs.org/docs/api-reference/core/useRecoilCallback)
・[`useCallback()`](https://reactjs.org/docs/hooks-reference.html#usecallback)
・[IT用語辞典 e-Words シグネチャ](http://e-words.jp/w/%E3%82%B7%E3%82%B0%E3%83%8D%E3%83%81%E3%83%A3.html)
・[IT用語辞典 e-Words インスタンス](http://e-words.jp/w/%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9.html)
・[IT用語辞典 e-Words トランザクション](http://e-words.jp/w/%E3%83%88%E3%83%A9%E3%83%B3%E3%82%B6%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3.html)
・[IT用語辞典 e-Words エンキュー](http://e-words.jp/w/%E3%82%AD%E3%83%A5%E3%83%BC.html#Section_%E3%82%A8%E3%83%B3%E3%82%AD%E3%83%A5%E3%83%BC/%E3%83%87%E3%82%AD%E3%83%A5%E3%83%BC)
・[useCallback](https://reactjs.org/docs/hooks-reference.html#usecallback)
・[みらい翻訳](https://miraitranslate.com/trial)

***

>## 全目次
* **前書き**
 * [①動機](https://qiita.com/Daichi44/items/4236857dac4a3365f434)
 * [②コアコンセプト](https://qiita.com/Daichi44/items/f6f8995a73387d104777)
 * [③インストール](https://qiita.com/Daichi44/items/b46d9659c8fcfad2c227)
 * [④入門](https://qiita.com/Daichi44/items/3356aaeb7a387b520621)
* **基本チュートリアル**
 * [⑤概要](https://qiita.com/Daichi44/items/ee1ced6040d06e33e165)
 * [⑥Atoms](https://qiita.com/Daichi44/items/d6c2472043b473c9819d)
 * [⑦Selectors](https://qiita.com/Daichi44/items/af3d6363ac3ce3e7af5a)
* **ガイド**
 * [⑧非同期データクエリ](https://qiita.com/Daichi44/items/47e9ac34c61c35531abb)
 * [⑨非同期状態・同期状態](https://qiita.com/Daichi44/items/ae631b34ac50fb9bbd1d)
 * [⑩Stateの永続性](https://qiita.com/Daichi44/items/45093185eb06fb4e1171)
* **APIリファレンス**
 * **Core** <br>
   •　[⑪ \<RecoilRoot /\>](https://qiita.com/Daichi44/items/b440f33d3831b86c62b9) <br>
   •　**State** <br>
   　・　[⑫`atom()`](https://qiita.com/Daichi44/items/0a9b9af69dddddbcd7e2) <br>
   　・　[⑬`selector()`](https://qiita.com/Daichi44/items/13912706763c22f9cbe9) <br>
   　・　[⑭Loadable](https://qiita.com/Daichi44/items/812aa5ebf149c849e108) <br>
   　・　[⑮`useRecoilState()`](https://qiita.com/Daichi44/items/2ec591ec3e952f1784c3) <br>
   　・　[⑯`useRecoilValue()`](https://qiita.com/Daichi44/items/f78a2ce0cfc01de354c5) <br>
   　・　[⑰`useSetRecoilState()`](https://qiita.com/Daichi44/items/ab0e98e0a48d0a59bdb4) <br>
   　・　[⑱`useResetRecoilState()`](https://qiita.com/Daichi44/items/a887cfa33260136b1d68) <br>
   　・　[⑲`useRecoilValueLoadable()`](https://qiita.com/Daichi44/items/679030df40e81a608be5) <br>
   　・　[⑳`useRecoilStateLoadable()`](https://qiita.com/Daichi44/items/f682baf85f0e2673abfc) <br>
   　・　[㉑`isRecoilValue()`](https://qiita.com/Daichi44/items/1c38716dc0738da3bc02) <br>
   •　**Snapshots** <br>
   　・　[㉒Snapshot](https://qiita.com/Daichi44/items/84a7218e76f62d41d0b7) <br>
   　・　[㉓`useRecoilTransactionObserver()`](https://qiita.com/Daichi44/items/de7e39f80cd1fdce8b7c) <br>
   　・　[㉔`useRecoilSnapshot()`](https://qiita.com/Daichi44/items/eda197468b0204349d5f) <br>
   　・　[㉕`useGotoRecoilSnapshot()`](https://qiita.com/Daichi44/items/0bbe5d6643462b55df11) <br>
   •　<font color="orange">**㉖ useRecoilCallback()**</font> <br>
   •　**雑録(Misc)** <br>
   　・　[㉗`useRecoilBridgeAcrossReactRoots()`](https://qiita.com/Daichi44/items/78292a5c30b1b1e4813f) <br>
 * **実用(utils)** <br>
   •　[㉘`atomFamily()`](https://qiita.com/Daichi44/items/c6046e45ba7447a64aed) <br>
   •　[㉙`selectorFamily()`](https://qiita.com/Daichi44/items/f552dfda4765596d83d7) <br>
   •　[㉚`constSelector()`](https://qiita.com/Daichi44/items/7e568ccfb6d2e504de13) <br>
   •　[㉛`errorSelector()`](https://qiita.com/Daichi44/items/6973c6d140b697b2c97e) <br>
   •　[㉜`waitForAll()`](https://qiita.com/Daichi44/items/b929ff5376d0672dafa0) <br>
   •　[㉝`waitForAny()`](https://qiita.com/Daichi44/items/e9720f6ceb7cea57b2ce) <br>
   •　[㉞`waitForNone()`](https://qiita.com/Daichi44/items/c9bb722022a003d72aa9) <br>
   •　[㉟`noWait()`](https://qiita.com/Daichi44/items/ca11fcef04d764ef13a8) <br>