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

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

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

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

## 目次

* **前書き**　[①](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** <br>
   　・　[⑫`atom()`](https://qiita.com/Daichi44/items/0a9b9af69dddddbcd7e2) <br>
   　・　<font color="orange">**⑬ selector()**</font> <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**　[㉒](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>
   •　[㉖`useRecoilCallback()`](https://qiita.com/Daichi44/items/0a276eb144f443a72efd) <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/13912706763c22f9cbe9#%E5%85%A8%E7%9B%AE%E6%AC%A1)は一番下にあります

***

# selector(options)

selectorは、Recoil内の関数または**派生state**を表します。​特定の依存関係値のセットに対して常に同じ値を返す副作用のない「純粋関数」と考えることができます。​get関数のみが指定されている場合、selectorは読み込み専用で、`RecoilValueReadOnly`オブジェクトを返します。​セットも指定されている場合は、書き込み可能な`RecoilState`オブジェクトを返します。

***

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

  get: ({
    get: GetRecoilValue
  }) => T | Promise<T> | RecoilValue<T>,

  set?: (
    {
      get: GetRecoilValue,
      set: SetRecoilState,
      reset: ResetRecoilState,
    },
    newValue: T | DefaultValue,
  ) => void,

  dangerouslyAllowMutability?: boolean,
})
```

```React
type ValueOrUpdater<T> = T | DefaultValue | ((prevValue: T) => T | DefaultValue);
type GetRecoilValue = <T>(RecoilValue<T>) => T;
type SetRecoilState = <T>(RecoilState<T>, ValueOrUpdater<T>) => void;
type ResetRecoilState = <T>(RecoilState<T>) => void;
```

* `key` - atomを内部的に識別するために使用される一意の文字列。​この文字列は、アプリケーション全体で他のatomおよびselectorに対して一意である必要があります。​永続性のために使用する場合は、実行間で安定している必要があります。
* `get` - 派生stateの値を評価する関数。​直接値を返すこともあれば、非同期`Promise`を返すこともありますし、同じ型を表す別のatomやselectorを返すこともあります。​次のプロパティを含む最初のパラメータとしてオブジェクトが渡されます。
  * `get` - 他のatom/selectorから値を取得するために使用する関数。​この関数に渡されるすべてのatom/selectorは、selectorの**依存関係**のリストに暗黙的に追加されます。​selectorの依存関係のいずれかが変更されると、selectorは再評価されます。
* `set?​` - このプロパティが設定されている場合、selectorは**書き込み可能**なstateを返します。​コールバックのオブジェクトを最初のパラメータおよび新しい入力値として渡される関数。​入力値は、`T`型の値か、ユーザーがselectorをリセットした場合は`DefaultValue`型のオブジェクトです。​コールバックには次のものがあります。
  * `get` - 他のatom/selectorから値を取得するために使用する関数。​この関数は、指定されたatom/selectorにselectorを登録しません。
  * `set` - 上流の Recoil state の値を設定する関数。​最初のパラメータは Recoil state で、2番目のパラメータは新しい値です。​新しい値は、リセットアクションを伝達するupdater関数または`DefaultValue`オブジェクトです。
* `dangerouslyAllowMutability` - selectorは派生stateの「純粋関数」を表し、同じ依存性入力値のセットに対して常に同じ値を返すべきです。​これを保護するために、selectorに格納されているすべての値はデフォルトでフリーズされます。​場合によっては、このオプションを使用してオーバーライドする必要があります。

***

単純な静的依存関係を持つselector:

```React
const mySelector = selector({
  key: 'MySelector',
  get: ({get}) => get(myAtom) * 100,
});
```

## Dynamic Dependencies (動的依存関係)

​読み取り専用selectorには、依存関係に基づいてselectorの値を評価する`get`メソッドがあります。​これらの依存関係のいずれかが更新されると、selectorが再評価されます。​依存関係は、selectorを評価するときに実際に使用するatomまたはselectorに基づいて動的に決定されます。​以前の依存関係の値に応じて、異なる追加の依存関係を動的に使用できます。​Recoilは、現在のデータフローグラフを自動的に更新し、selectorが現在の依存関係のセットからの更新のみに登録されるようにします。

​この例では、`mySelector`は`toggleState`の状態に応じて`selectorA`または`selectorB`と`toggleState`のatomに依存します。

```React
const toggleState = atom({key: 'Toggle', default: false});

const mySelector = selector({
  key: 'MySelector',
  get: ({get}) => {
    const toggle = get(toggleState);
    if (toggle) {
      return get(selectorA);
    } else {
      return get(selectorB);
    }
  },
});
```

## Writeable Selectors (書き込み可能なselector)
​双方向selectorは、入力値をパラメータとして受け取り、それを使用して、データフローグラフに沿って上流に変更を伝播することができます。​ユーザーはselectorに新しい値を設定することも、selectorをリセットすることもできるため、入力値は、selectorが表すのと同じ型、またはリセットアクションを表す`DefaultValue`オブジェクトのいずれかになります。

​この単純なselectorは、基本的にatomをラップしてフィールドを追加します。​set操作とreset操作を単に上流のatomに渡すだけです。

```React
const proxySelector = selector({
  key: 'ProxySelector',
  get: ({get}) => ({...get(myAtom), extraField: 'hi'}),
  set: ({set}, newValue) => set(myAtom, newValue),
});
```

​このselectorはデータを変換するため、入力値が`DefaultValue`かどうかを確認する必要があります。

```React
const transformSelector = selector({
  key: 'TransformSelector',
  get: ({get}) => get(myAtom) * 100,
  set: ({set}, newValue) =>
    set(myAtom, newValue instanceof DefaultValue ? newValue : newValue / 100),
});
```

## Asynchronous Selectors (非同期selector)
​selectorは非同期評価関数を持つこともでき、出力値に`Promise`を返します。​
詳細については、[このガイド](https://qiita.com/Daichi44/items/47e9ac34c61c35531abb)を参照してください。

```React
const myQuery = selector({
  key: 'MyQuery',
  get: async ({get}) => {
    return await myAsyncQuery(get(queryParamState));
  }
});
```

## Example (Synchronous) (同期処理の例)

```React
import {atom, selector, useRecoilState, DefaultValue} from 'recoil';

const tempFahrenheit = atom({
  key: 'tempFahrenheit',
  default: 32,
});

const tempCelcius = selector({
  key: 'tempCelcius',
  get: ({get}) => ((get(tempFahrenheit) - 32) * 5) / 9,
  set: ({set}, newValue) =>
    set(
      tempFahrenheit,
      newValue instanceof DefaultValue ? newValue : (newValue * 9) / 5 + 32
    ),
});

function TempCelcius() {
  const [tempF, setTempF] = useRecoilState(tempFahrenheit);
  const [tempC, setTempC] = useRecoilState(tempCelcius);
  const resetTemp = useResetRecoilState(tempCelcius);

  const addTenCelcius = () => setTempC(tempC + 10);
  const addTenFahrenheit = () => setTempF(tempF + 10);
  const reset = () => resetTemp();

  return (
    <div>
      Temp (Celcius): {tempC}
      <br />
      Temp (Fahrenheit): {tempF}
      <br />
      <button onClick={addTenCelcius}>Add 10 Celcius</button>
      <br />
      <button onClick={addTenFahrenheit}>Add 10 Fahrenheit</button>
      <br />
      <button onClick={reset}>>Reset</button>
    </div>
  );
}
```

## Example (Asynchronous) (非同期処理の例)

```React
import {selector, useRecoilValue} from 'recoil';

const myQuery = selector({
  key: 'MyDBQuery',
  get: async () => {
    const response = await fetch(getMyRequestUrl());
    return response.json();
  },
});

function QueryResults() {
  const queryResults = useRecoilValue(myQuery);

  return (
    <div>
      {queryResults.foo}
    </div>
  );
}

function ResultsSection() {
  return (
    <React.Suspense fallback={<div>Loading...</div>}>
      <QueryResults />
    </React.Suspense>
  );
}
```

より複雑な例については、[このガイド](https://qiita.com/Daichi44/items/47e9ac34c61c35531abb)を参照してください。

***

### 参考サイト
・[公式ドキュメント](https://recoiljs.org/docs/api-reference/core/selector)
・[みらい翻訳](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>
   　・　<font color="orange">**⑬ selector()**</font> <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>
   •　[㉘`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>