【React】Zustandによるグローバル状態管理

Zustandとは

React向けの軽量・高速・シンプルな状態管理ライブラリで、フックベースの直感的なAPIを持ち、Reduxよりも少ないコードで状態管理を実現可能です。グローバルな(アプリ全体を範囲とした)状態管理をしたいときに利用します。

インストール方法

npmによってインストール可能です。

npm install zustand

サンプルコード:カウンターを状態として管理する

ストアの定義

store.tsにZustandストアを定義します。

import { create } from 'zustand'

// 状態の型定義
type CounterState = {
  count: number
  increment: () => void
  decrement: () => void
  reset: () => void
}

// Zustandストア作成
export const useCounterStore = create<CounterState>((set) => ({
  count: 0,
  increment: () => set((state) => ({ count: state.count + 1 })),
  decrement: () => set((state) => ({ count: state.count - 1 })),
  reset: () => set({ count: 0 }),
}))

createはZustandが提供するストアを生成する関数であり、ストアの型をジェネリクスに指定し、引数にはストアの初期値とアクションを表す関数を与えます。引数として与えた関数にはset(Zustandが提供する状態を更新するための関数)を引数に指定します。setには原則、現在の状態(state)を入力として受け取り、新しい状態のオブジェクトを返す関数を引数として与えます。例外的に直接オブジェクトを与えることもでき、その場合は現在の状態とは無関係にオブジェクトで指定した値にストアの値を更新します。

ストアの使用

定義したストアをReactコンポーネントで使用するには以下のように書きます。コンポーネントの名称をCounter.tsxとした例です。

import React from 'react'
import { useCounterStore } from './store'  // 自分で定義したストア

export const Counter = () => {
  // ストアの値とアクションを表す関数をフックから取得する
  const { count, increment, decrement, reset } = useCounterStore()

  return (
    <div style={{ textAlign: 'center' }}>
      <h1>Count: {count}</h1>
      <button onClick={increment}>+</button>
      <button onClick={decrement}>-</button>
      <button onClick={reset}>リセット</button>
    </div>
  )
}