Zustand Zustand State Library

Last updated: 2026-11-02

Zustand Zustand State Library

Zustand is a minimal global state library: create defines a store, components call it like a custom Hook, the state is shared across components and no Provider is needed. The core is just two functions, set and get, there is no boilerplate, and it is the popular replacement for Redux in small and medium projects where a full store with actions, reducers and middleware would be too much ceremony.

GroupRouting & State Mgmt
KindLibrary
SinceZustand v4 / v5

ℹ️ Info The editor transpiles JSX to JavaScript and renders the real UI in a sandbox; components mount automatically — no manual render call needed.

📝 Syntax

import { create } from 'zustand'

const useStore = create((set, get) => ({
  count: 0,                                       // state
  inc: () => set(s => ({ count: s.count + 1 })),  // action
  reset: () => set({ count: 0 })
}))

// Inside a component (no Provider required)
const count = useStore(s => s.count)   // subscribe to a slice, update precisely
const inc = useStore(s => s.inc)

⚙️ Parameters

selectorThe state selector passed when calling the store Hook, e.g. s => s.count; omit it and you subscribe to the whole store, so any change re-renders.

Returns:create returns a Hook: calling it returns the selected slice of state; set merges the state and triggers updates in the subscribed components, get reads the latest state.

▶ Example

The example runs out of the box: it auto-renders when expanded, and edits take effect instantly.

Output:

Clicking the A button changes the number that component B reads - the two components share no parent that passes props, the external store keeps them in sync, and that is exactly how Zustand works (simulated demo).

💡 Key Points

💡 Tip A selector that returns an object (s => ({ a: s.a, b: s.b })) creates a new reference every time and causes extra renders; use a shallow comparison or split it into several calls.
ℹ️ Info The persist middleware syncs the store to localStorage and the devtools middleware plugs into Redux DevTools - both are a single import away.
⚠️ Warning set is a shallow merge: for nested objects spread them yourself with set(s => ({ deep: { ...s.deep, x: 1 } })), there is no automatic deep merge.
More case studies coming soon.

📚 Related Tutorials

❓ FAQ

Q Why does Zustand not need a Provider?
A The state lives in a module level variable and does not depend on Context; components subscribe to it directly with useSyncExternalStore, so it is shared across components by nature.
Q How do I persist the state?
A Import { persist } from 'zustand/middleware' and wrap the creator in persist(fn, { name: 'key' }) inside create; it reads and writes localStorage for you.
Q How do I write an async action?
A An action is just a function: fetchUser: async () => { const data = await api(); set({ user: data }) }. There is no distinction between thunks and reducers.
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏