Recoil公式ドキュメント 翻訳㉘ APIリファレンス-Core-実用(Utils)-atomFamily()

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

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

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

## 目次

* **前書き**　[①](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**　[⑪](https://qiita.com/Daichi44/items/b440f33d3831b86c62b9)　[⑫](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)　[㉒](https://qiita.com/Daichi44/items/84a7218e76f62d41d0b7)　[㉓](https://qiita.com/Daichi44/items/de7e39f80cd1fdce8b7c)　[㉔](https://qiita.com/Daichi44/items/eda197468b0204349d5f)　[㉕](https://qiita.com/Daichi44/items/0bbe5d6643462b55df11)　[㉖](https://qiita.com/Daichi44/items/0a276eb144f443a72efd)　[㉗](https://qiita.com/Daichi44/items/78292a5c30b1b1e4813f)
 * **実用(utils)** <br>
   •　<font color="orange">**㉘ atomFamily()**</font> <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>



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

***

# atomFamily(options)

​書き込み可能な`RecoilState` [atom](https://qiita.com/Daichi44/items/0a9b9af69dddddbcd7e2)を返す関数を返します。

***

```React
function atomFamily<T, Parameter>({
  key: string,

  default:
    | RecoilValue<T>
    | Promise<T>
    | T
    | (Parameter => T | RecoilValue<T> | Promise<T>),

  effects_UNSTABLE?:
    | $ReadOnlyArray<AtomEffect<T>>
    | (P => $ReadOnlyArray<AtomEffect<T>>),

  dangerouslyAllowMutability?: boolean,
}): Parameter => RecoilState<T>
```

* ​`key` - atomを内部的に識別するために使用される一意の文字列。​この文字列は、アプリケーション全体で他のatomおよびselectorに対して一意である必要があります。
* `default` - atomの初期値。​直接値を指定するか、デフォルト値を表す`RecoilValue`または`Promise`を指定するか、あるいはデフォルト値を取得する関数を指定します。​コールバック関数には、`atomFamily`関数の呼び出し時に使用されるパラメータのコピーが渡されます。
* `effects_UNSTABLE` - Atom Effectsのオプションの配列、あるいはfamilyパラメータに基づいて配列を取得するためのコールバック。
* `dangerouslyAllowMutability` - Recoilは、atomのstateの変化に依存して、atomを再描画に使用するコンポーネントに通知するタイミングを決定します。​atomの値が変更された場合、これをバイパスし、登録するコンポーネントに適切に通知せずにstateを変更する可能性があります。​これを防ぐために、保存されている値はすべて凍結されます。​場合によっては、このオプションを使用してこれをオーバーライドすることが望ましいこともあります。

***

​atomはRecoil stateの断片を表します。​atomは<RecoilRoot>ごとにアプリケーションによって作成され、登録されます。しかし、stateがグローバルでない場合はどうなりますか？ ​stateがコントロールの特定のインスタンスに関連付けられている場合、または特定の要素に関連付けられている場合はどうなりますか？ ​例えば、あなたのアプリはユーザが動的に要素を追加することができ、各要素はその位置のようなstateを持っているUIプロトタイピングツールかもしれません。​理想的には、各元素はそれぞれのstate atomをもちます。​これはメモパターンを使って自分で実装できます。​しかし、Recoilは`atomFamily`ユーティリティでこのパターンを提供します。`atomFamily`は、atomの集合を表します。​`atomFamily`を呼び出すと、渡されたパラメータに基づいて`RecoilState`atomを提供する関数が返されます。

​`atomFamily`は基本的に、パラメータからatomへのmapを提供します。​`atomFamily`に提供する必要があるkeyは1つだけで、基礎となる各atomに固有のkeyが生成されます。​これらのatom keyは持続性のために使用できるため、アプリケーションの実行中に安定している必要があります。​パラメータは異なるコールサイトで生成されることもあり、同じ基底atomを使用する同等のパラメータが必要です。​したがって、`atomFamily`パラメータのreference-equalityの代わりにvalue-equalityが使用されます。​これにより、パラメータに使用できるタイプが制限されます。​`atomFamily`は、プリミティブ型、または配列、オブジェクト、プリミティブ型を含む配列またはオブジェクトを受け入れます。

## サンプルコード

```React
const elementPositionStateFamily = atomFamily({
  key: 'ElementPosition',
  default: [0, 0],
});

function ElementListItem({elementID}) {
  const position = useRecoilValue(elementPositionStateFamily(elementID));
  return (
    <div>
      Element: {elementID}
      Position: {position}
    </div>
  );
}
```

​`atomFamily()`は、単純な[`atom()`](https://qiita.com/Daichi44/items/0a9b9af69dddddbcd7e2)とほとんど同じオプションを取ります。​ただし、既定値をパラメータ化することもできます。​つまり、パラメータ値を受け取り、実際のデフォルト値を返す関数を提供できます。​たとえば、次のようになります。

```React
const myAtomFamily = atomFamily({
  key: ‘MyAtom’,
  default: param => defaultBasedOnParam(param),
});
```

または`selector`の代わりに[`selectorFamily`](https://qiita.com/Daichi44/items/f552dfda4765596d83d7)を使用すると、デフォルトselectorでパラメータ値にアクセスすることもできます。

```React
const myAtomFamily = atomFamily({
  key: ‘MyAtom’,
  default: selectorFamily({
    key: 'MyAtom/Default',
    get: param => ({get}) => {
      return computeDefaultUsingParam(param);
    },
  }),
});
```

## Subscriptions (購読)
​すべての要素のstate mapを持つ単一のatomを保存しようとするよりも、各要素の個別のatomにこのパターンを使用する方が優れている点の1つは、すべての要素がそれぞれ独自のサブスクリプションを保持することです。​そのため、1つの要素の値を更新すると、そのatomのみに登録しているReactコンポーネントのみが更新されます。

## Persistence (持続性)
​永続性オブザーバは、使用されるパラメータ値のシリアライズに基づいて一意のkeyを持つ個別のatomとして、各パラメータ値のstateを永続化します。​したがって、プリミティブまたはプリミティブを含む単純な合成オブジェクトであるパラメータのみを使用することが重要です。​カスタムクラスまたは関数は使用できません。

​同じkeyに基づいた新しいバージョンのアプリでは、単純なatomを`atomFamily`に"アップグレード"することができます。​これを行うと、古い単純なkeyを持つ永続化された値も引き続き読み取ることができ、新しい`atomFamily`のすべてのパラメーター値は、デフォルトで単純なatomの永続化されたstateになります。​ただし、`atomFamily`のパラメータのフォーマットを変更した場合、変更前に保持されていた以前の値は自動的に読み込まれません。​ただし、以前のパラメータフォーマットに基づいて値をルックアップする場合は、デフォルトのセレクタまたはバリデータにロジックを追加できます。​将来的には、このパターンの自動化を支援したいと考えています。

***

### 参考サイト
・[公式ドキュメント](https://recoiljs.org/docs/api-reference/utils/atomFamily)
・[みらい翻訳](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>
   •　[㉖`useRecoilCallback()`](https://qiita.com/Daichi44/items/0a276eb144f443a72efd) <br>
   •　**雑録(Misc)** <br>
   　・　[㉗`useRecoilBridgeAcrossReactRoots()`](https://qiita.com/Daichi44/items/78292a5c30b1b1e4813f) <br>
 * **実用(utils)** <br>
   •　<font color="orange">**㉘ atomFamily()**</font> <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>