🏗️

Recoilで状態管理

2021/06/18に公開

Recoilとは

  • Reactで使用される、Facebookによって提唱された状態管理フレームワーク
  • Reduxと同様、fluxをベースにしている

Atom

  • 一意のkeyと、それと紐づく状態を保持する
  • 1つのAtomで1つの状態を保持する
  • Hooks APIのuseRecoilStateで呼び出すことができる
  • ReduxでいうStore?

Selector

  • 複数のAtomに基づくことができる純粋関数
  • Atomを加工(フィルター)して返したりできる
  • Hooks APIのuseRecoilValueで呼び出すことができる
  • ReduxでいうReducer?

メリット

  • Reduxと比較して構成が小さく使いやすい
  • Hooks APIのuseStateと同じノリで使える

サンプル

https://recoiljs.org/docs/introduction/getting-started
公式のゲットスタンダートを実行してみる。

react-appを生成。

$ npx create-react-app recoil-test

recoilを追加。

$ yarn add recoil

ソースはこんな感じ。

// [/src/App.js]

import React from 'react';
import { RecoilRoot } from 'recoil';

import CharacterCounter from "./modules/CharacterCounter";

function App() {
  return (
    // コンポーネントをRecoilRootで囲う
    <RecoilRoot>
      <CharacterCounter />
    </RecoilRoot>
  );
}

export default App;
// [/src/modules/CharacterCounter.js]

import React from 'react';
import { atom, selector, useRecoilState, useRecoilValue } from 'recoil';

// 入力された文字を保持するAtom
const textState = atom({
  key: 'textState',
  default: '',
});

// textStateを受け取って、文字数を返す純粋関数
const charCountState = selector({
  key: 'charCountState',
  get: ({get}) => {
    const text = get(textState);
    return text.length;
  },
});

function CharacterCounter() {
  return (
    <div>
      <TextInput />
      <CharacterCount />
    </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>
  );
}

function CharacterCount() {
  const count = useRecoilValue(charCountState);
  return (
    <div>Character Count: {count}</div>
  );
}

export default CharacterCounter;

入力前

入力後

Reduxに比べてコンパクトでわかりやすい。嬉しい。

Discussion