Next.js starter your AI actually understands. Ship internal tools in days not weeks. Pre-order $199 $499 → [Get it now]

How to use Zustand in React

Zustand is a minimal, hook-based state management library for React that provides global state without Redux’s actions, reducers, and providers — just a store and a hook. As the creator of CoreUI with 25 years of front-end development experience, I use Zustand when an application needs shared state across many components but the full Redux setup would be overkill. Zustand stores are plain JavaScript objects with state and actions defined together, and any component can subscribe to exactly the slice of state it needs. The setup is a single create() call — no Provider, no boilerplate.

Create a store with state and actions.

// store/useCartStore.js
import { create } from 'zustand'
import { persist } from 'zustand/middleware'

export const useCartStore = create(
  persist(
    (set, get) => ({
      // State
      items: [],
      total: 0,

      // Actions
      addItem: (product) => {
        const items = get().items
        const existing = items.find(i => i.id === product.id)

        const updatedItems = existing
          ? items.map(i => i.id === product.id
              ? { ...i, quantity: i.quantity + 1 }
              : i
            )
          : [...items, { ...product, quantity: 1 }]

        const total = updatedItems.reduce((sum, i) => sum + i.price * i.quantity, 0)
        set({ items: updatedItems, total })
      },

      removeItem: (id) => {
        const items = get().items.filter(i => i.id !== id)
        const total = items.reduce((sum, i) => sum + i.price * i.quantity, 0)
        set({ items, total })
      },

      clearCart: () => set({ items: [], total: 0 })
    }),
    {
      name: 'cart-storage' // persists to localStorage automatically
    }
  )
)

create() returns a hook. set updates the store, get reads current state. The persist middleware serializes state to localStorage — the cart survives page refreshes with no extra code.

Using the Store in Components

Subscribe to exactly the state each component needs.

// CartIcon.jsx - only subscribes to item count
import { useCartStore } from './store/useCartStore'

export function CartIcon() {
  const itemCount = useCartStore(state =>
    state.items.reduce((sum, i) => sum + i.quantity, 0)
  )

  return <span>🛒 {itemCount}</span>
}
// ProductCard.jsx - only subscribes to addItem action
import { useCartStore } from './store/useCartStore'

export function ProductCard({ product }) {
  const addItem = useCartStore(state => state.addItem)

  return (
    <div>
      <h3>{product.name}</h3>
      <button onClick={() => addItem(product)}>Add to Cart</button>
    </div>
  )
}
// CartSummary.jsx - subscribes to items and total
import { useCartStore } from './store/useCartStore'

export function CartSummary() {
  const { items, total, removeItem } = useCartStore()

  return (
    <div>
      {items.map(item => (
        <div key={item.id}>
          {item.name} × {item.quantity} = ${(item.price * item.quantity).toFixed(2)}
          <button onClick={() => removeItem(item.id)}>Remove</button>
        </div>
      ))}
      <strong>Total: ${total.toFixed(2)}</strong>
    </div>
  )
}

Passing a selector to useCartStore(state => state.addItem) subscribes only to that property. CartIcon re-renders only when item count changes; ProductCard never re-renders on cart changes because it only subscribes to the addItem action (which never changes).

Best Practice Note

This is the same lightweight state pattern we recommend in CoreUI React templates for shopping cart, theme, and user preference state. No Provider wrapper is needed — Zustand stores are global singletons that any component can import and use directly. For server state (API data), use RTK Query or TanStack Query alongside Zustand rather than storing API responses in Zustand. See how to use Redux in React when you need DevTools, middleware, or the full Redux ecosystem.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
What is the Difference Between Null and Undefined in JavaScript
What is the Difference Between Null and Undefined in JavaScript

The Wacky World of JavaScript: Unraveling the Oddities
The Wacky World of JavaScript: Unraveling the Oddities

How to Get Unique Values from a JavaScript Array
How to Get Unique Values from a JavaScript Array

JavaScript printf equivalent
JavaScript printf equivalent

Answers by CoreUI Core Team