業務で Recoil を扱うことになったので、その学習メモ。
Recoil は Redux のようにグローバルステートを扱う Facebook 謹製のライブラリ。ひとまず理解のために Getting Started をやってみます。

RecoilRoot

recoil state を使用するコンポーネントは、親ツリーのどこかに RecoilRoot を表示する必要があります。これを置くのに良い場所は、ルートコンポーネントです。

https://recoiljs.org/docs/introduction/getting-started
import {
  RecoilRoot,
  atom,
  selector,
  useRecoilState,
  useRecoilValue,
} from "recoil";

export default function App() {
  return (
    <RecoilRoot>
      <CharacterCounter />
    </RecoilRoot>
  );
}

Atom

atom はステートの断片を表します。atom はどのコンポーネントからも読み書きが可能です。atom の値を読み取るコンポーネントは、暗黙のうちにその atom を購読していることになります。そのため、atom の更新は、その atom を購読しているコンポーネントの再レンダリングにつながります。

const textState = atom({
  key: "textState", // 他のatomにないユニークなID
  default: "" // このatomのデフォルト値
});

atom への read / write が必要なコンポーネントは、以下のように useRecoilState() を使います。

function CharacterCounter() {
  return (
    <div>
      <TextInput />
      <CharacterCoutne />
    </div>
  );
}

function TextInput() {
  const [text, setText] = useRecoilState(textState);

  const onChange = (event) => [setText(event.target.value)];

  return (
    <div>
      <input type="text" value={text} onChange={onChange} />
      <br />
      Echo: {text}
    </div>
  );
}

Selector

セレクタは、派生した状態の一部を表します。派生状態とは、状態の変換のことです。派生状態は、与えられた状態を何らかの方法で変更する純粋な関数に状態を渡したときの出力と考えることができます。

https://recoiljs.org/docs/introduction/getting-started

翻訳がしっくりこないが useMemo のようなものか?

const charCountState = selector({
  key: "charCountState",
  get: ({ get }) => {
    const text = get(textState);

    return text.length;
  }
});

useRecoilValueを使ってセレクタにアクセスが可能。

function CharacterCount() {
  const count = useRecoilValue(charCountState);

  return <>Character Count: {count}</>;
}

Sample