自己紹介
著者のイナバくんは、ニジボックスでフロントエンドエンジニアをしていて、とある会社に常駐しています。
プライベートでは、登山やカメラや禁煙などに嗜んでいます。
イナバくんはグローバルステート童貞ですが、業務でライブラリ選定することになったので、速やかにインプットします。
業務では、ローカルステート・サーバーキャッシュはすでに使っています。
- ローカルステート: useState, useReducer
- サーバーキャッシュ: ReactQuery
ライブラリのリスト
npm trendsで2023/12 現在のインストール数の順番は下記のとおり。
- Redux
- Zustand
- Jotai
- Recoil
※ React Context API も比較対象とします。
Redux がやはり圧倒的シェアを持っています。
1. Atom 方式
1-1. Recoil
Recoilは現在ライブラリ開発が停止しているので使うことはないですが、Atom方式の思想を理解するためにインプットします。
// atomは複数作成できる
export const globalState = atom({
key: 'globalState', // 一意のキー
default: '', // デフォルト値
});
// 複数のページ・コンポーネントで使える
const [state, setState] = useRecoilState(globalState);
useStateを複数のページに跨って共有できるような書き味。
中央集権的に管理されているStore型と違い、Atomは独立・分散配置されています。
Atom方式では、データの流れは親→子→孫 とトップダウンではなく、任意のコンポーネントでデータを定義して、双方向に渡すことができます。
1-2. Jotai
Recoil インスパイアのライブラリ。
// atomは複数作成できる
export const countAtom = atom(0); // 初期値 = 0
// 複数のページ・コンポーネントで使える
const [count, setCount] = useAtom(countAtom);
書き味はRecoilとほぼ同じ。
JotaiはRecoilと違ってAtomのkeyを設定する必要がありません。
2. Store 方式
2-1. Redux(+ Redux Toolkit)
Reduxは概念が多くて大変なんだクポ〜。
2-2. Context API(useContext)
export const sampleContext = createContext();
const Parent = () => {
const [count, setCount] = useState(0); // コンテキストに入れるstate
return (
// contextの数だけProviderを作成する必要あり
<sampleContext.Provider value={count}>
<Child/>
</sampleContext.Provider>
)
}
const Child = () => {
const context = useContext(sampleContext); // contextを取得
return <p>{context}</p>;
}
コードはシンプルで分かりやすいですが、グローバルステートの数が増えるとProviderネスト地獄になります。
また、コンテキストを更新するとステートを使っているコンポーネントは再レンダリングされます。
小規模のプロダクトでグローバルステートが少ない場合はマッチしそうです。
2-3. Zustand
Redux インスパイア。