liveBook · Manning

Zustand

As explained in React in Depth

zustand is a small JavaScript state-management library based on centralized stores and hooks.

zustand is a compact option for shared React state. Its create() function returns a hook that components can call wherever they need the same state and actions. Unlike a reducer-and-context setup, this does not require a context provider or consumer hook. That simplicity makes it attractive when a data layer needs shared state without much wiring. section 8.6 section 8.6.1

A goal-tracking data layer shows the main implementation choices:

  • Define state values and update callbacks together in useData. Wrap the store with immer middleware to write updates against a draft, and with persist middleware to save data to local storage. section 8.6.1 section 8.6.2
  • Expose focused hooks that select only what their callers need. For example, useAddThing selects the addThing action, while useCurrentThing selects the current item. section 8.6.2
  • Keep a DataProvider only if an interchangeable data-layer interface requires it; in this variant, it does not distribute state. section 8.6.2
Listing 8.25 src/data/useData.js
import { create } from "zustand";
import { v4 as uuid } from "uuid";
import { persist } from "zustand/middleware";
import { immer } from "zustand/middleware/immer";
export const useData = create(    #1
  persist(     #2
    immer((set) => ({   #2
      things: [], 
      currentThing: null,
      seeThing: (newThing) =>
        set((draft) => {
          draft.currentThing = newThing;
        }),
      seeAllThings: () =>
        set((draft) => {
          draft.currentThing = null;
        }),
      addThing: (name) =>
        set((draft) => {
          draft.things.push({ id: uuid(), name, done: [] });
        }),
      removeThing: (id) =>
        set((draft) => {
          const index = draft.things.findIndex((thing) => thing.id === id);
          if (index !== -1) {
            draft.things.splice(index, 1);
            if (id === draft.currentThing) {
              draft.currentThing = null;
            }
          }
        }),
      doThing: (id) =>
        set((draft) => {
          const thing = draft.things.find((thing) => thing.id === id);
          thing.done.push(Date.now());
        }),
      undoThing: (id, index) =>
        set((draft) => {
          const thing = draft.things.find((thing) => thing.id === id);
          thing.done.splice(index, 1);
        }),
    })),
    { name: "100-things-zustand" }
  )
);

The useData listing shows create() wrapping persist and immer around a store of goal-tracking values and actions. section 8.6.2

Choose zustand for its low setup cost, not because every application needs another state library. React context with useReducer can go far, and Redux Toolkit remains an alternative. zustand offers fewer built-in patterns for organizing multiple unrelated stores, which can make larger systems harder to structure. It can also have a narrower job: when server data is handled through queries and mutations, a zustand hook can hold only the local UI choice between list and detail view. section 8.9 section 9.3.3

How React in Depth covers it

How deep it goes
Works through store middleware and selector hooks, then compares setup and scaling costs; it does not provide a pattern for multiple unrelated stores.
Examples
Uses a goal-tracking application with a shared useData store, focused selector hooks, and an optional interface-only provider.
What it assumes
Assumes familiarity with React hooks and reducer-based state; compares zustand with context wiring rather than teaching those foundations from zero.
What you can do after
Build it from scratch: create a zustand store with actions, persistence, and focused hooks for a React data layer.
How it connects
Connects reducer-based state, React context, Immer, local storage persistence, Redux Toolkit, and server-data queries.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of React in Depth. The section links point to the parts of the book it draws on.