Skip to content
D
Documentation

Update Map and Set state

how-to
1 min readUpdated

When store state contains a Map or Set, create a new collection instance for each update so a component selecting that collection can detect the change. The example below updates a stock Map and toggles a featured-item Set in a mounted React component.

Create actions that replace the collection

Use create to put the collections and their actions in one store. Each action copies the current collection, changes the copy, and returns it as the updated field.

tsx
import { createRoot } from 'react-dom/client'
import { create } from 'zustand'

type InventoryStore = {
  stock: Map<string, number>
  featured: Set<string>
  addTea: () => void
  toggleFeaturedTea: () => void
}

const useInventoryStore = create<InventoryStore>()((set) => ({
  stock: new Map<string, number>([['tea', 2]]),
  featured: new Set<string>(),
  addTea: () =>
    set((state) => ({
      stock: new Map(state.stock).set('tea', (state.stock.get('tea') ?? 0) + 1),
    })),
  toggleFeaturedTea: () =>
    set((state) => {
      const featured = new Set(state.featured)
      if (featured.has('tea')) {
        featured.delete('tea')
      } else {
        featured.add('tea')
      }
      return { featured }
    }),
}))

export default function App() {
  const stock = useInventoryStore((state) => state.stock)
  const featured = useInventoryStore((state) => state.featured)
  const addTea = useInventoryStore((state) => state.addTea)
  const toggleFeaturedTea = useInventoryStore((state) => state.toggleFeaturedTea)

  return (
    <main>
      <h1>Inventory</h1>
      <p>Tea in stock: {stock.get('tea') ?? 0}</p>
      <p>Featured: {featured.has('tea') ? 'Tea' : 'None'}</p>
      <button onClick={addTea}>Add one tea</button>
      <button onClick={toggleFeaturedTea}>Toggle featured tea</button>
    </main>
  )
}

const container = document.getElementById('root')!
createRoot(container).render(<App />)

Place a <div id="root"></div> in the page and run this as the React entry module. It mounts the component, which initially renders two teas and no featured item. Clicking Add one tea replaces the Map and increases the displayed count; clicking Toggle featured tea replaces the Set and switches the displayed value between “Tea” and “None.”

The inventory shows two teas in stock and no featured item.

Choose the update for the collection

For the immutable-update and shallow-merge rules, see Immutable state updates. These collection-specific operations return the new value for the field you change:

Collection updateNew value to return
Set one map entrynew Map(state.items).set(key, value)
Delete one map entryCopy with new Map(state.items), call delete(key) on the copy, then return it
Add one set itemnew Set(state.items).add(item)
Delete or toggle a set itemCopy with new Set(state.items), change the copy, then return it
Clear a collectionReturn new Map() or new Set() for that field

If you initialize an empty collection, provide its element types, as in new Map<string, number>() or new Set<string>(). This gives TypeScript the key, value, or item types that later updates use.

Avoid mutating the stored instance

For why an update must produce a changed reference, see Immutable state updates.

For other immutable-update pitfalls, see Update nested state and React quick start.

See it running

Open the Map and Set demo to see the collection updates in a running app.

Was this page helpful?

Update Map and Set state — zustand · GPT-6 Luna