Context と Hooks でグローバルな状態を管理する一番シンプルな方法

  • Redux を使わずに React だけでグローバルな状態を管理したい
  • Context API はやや複雑なのでシンプルにしたい
  • グローバルな状態は末端のコンポーネントでも更新できるようにしたい

これらを満たすには、 Context API と Hooks API を組み合わせる。シンプルだが強力。でも少し欠点もある。

以下、TypeScript で書いた。

ログイン中のユーザーをグローバルに管理したいとして、Provider側。

interface User {
  id: string
  name: string
}

type MaybeUser = User | null

interface UserContextValute {
  user: MaybeUser
  setUser: Dispatch<SetStateAction<MaybeUser>>
}

const UserContext = React.createContext<UserContextValute>(
  (null as any) as UserContextValute,
)

const UserProvider = (props: { children: ReactChild }) => {
  const [user, setUser] = useState<MaybeUser>(null)
  return (
    <UserContext.Provider value={{ user, setUser }}>
      {props.children}
    </UserContext.Provider>
  )
}

そして使う側のコンポーネントはこう。

const UserLabel = () => {
  const { user } = useContext(UserContext)
  return <span>{user}</span>
}

欠点として、あまり複雑なことはできない。たとえば複数の状態を組み合わせて非同期関数を酷使しながら更新するといったときに困りそう。