mirror of
https://github.com/pmndrs/zustand.git
synced 2025-12-08 19:45:52 +00:00
docs: update map and set guide (#3258)
* Enhance Maps and Sets usage documentation in Zustand Expanded the documentation on using Maps and Sets in Zustand, including guidelines for reading and updating these data structures. Added examples for creating new instances and explained the importance of reference changes for state updates. * feat: update format
This commit is contained in:
parent
20ad3f8891
commit
95850110ab
@ -3,25 +3,113 @@ title: Map and Set Usage
|
||||
nav: 10
|
||||
---
|
||||
|
||||
You need to wrap Maps and Sets inside an object. When you want its update to be reflected (e.g. in React),
|
||||
you do it by calling `setState` on it:
|
||||
# Map and Set in Zustand
|
||||
|
||||
**You can view a codesandbox here: https://codesandbox.io/s/late-https-bxz9qy**
|
||||
Map and Set are mutable data structures. To use them in Zustand, you must create new instances when updating.
|
||||
|
||||
```js
|
||||
import { create } from 'zustand'
|
||||
## Map
|
||||
|
||||
const useFooBar = create(() => ({ foo: new Map(), bar: new Set() }))
|
||||
### Reading a Map
|
||||
|
||||
function doSomething() {
|
||||
// doing something...
|
||||
```typescript
|
||||
const foo = useSomeStore((state) => state.foo)
|
||||
```
|
||||
|
||||
// If you want to update some React component that uses `useFooBar`, you have to call setState
|
||||
// to let React know that an update happened.
|
||||
// Following React's best practices, you should create a new Map/Set when updating them:
|
||||
useFooBar.setState((prev) => ({
|
||||
foo: new Map(prev.foo).set('newKey', 'newValue'),
|
||||
bar: new Set(prev.bar).add('newKey'),
|
||||
}))
|
||||
### Updating a Map
|
||||
|
||||
Always create a new Map instance:
|
||||
|
||||
```ts
|
||||
// Update single entry
|
||||
set((state) => ({
|
||||
foo: new Map(state.foo).set(key, value),
|
||||
}))
|
||||
|
||||
// Delete entry
|
||||
set((state) => {
|
||||
const next = new Map(state.foo)
|
||||
next.delete(key)
|
||||
return { foo: next }
|
||||
})
|
||||
|
||||
// Update multiple entries
|
||||
set((state) => {
|
||||
const next = new Map(state.foo)
|
||||
next.set('key1', 'value1')
|
||||
next.set('key2', 'value2')
|
||||
return { foo: next }
|
||||
})
|
||||
|
||||
// Clear
|
||||
set({ foo: new Map() })
|
||||
```
|
||||
|
||||
## Set
|
||||
|
||||
### Reading a Set
|
||||
|
||||
```ts
|
||||
const bar = useSomeStore((state) => state.bar)
|
||||
```
|
||||
|
||||
### Updating a Set
|
||||
|
||||
Always create a new Set instance:
|
||||
|
||||
```ts
|
||||
// Add item
|
||||
set((state) => ({
|
||||
bar: new Set(state.bar).add(item),
|
||||
}))
|
||||
|
||||
// Delete item
|
||||
set((state) => {
|
||||
const next = new Set(state.bar)
|
||||
next.delete(item)
|
||||
return { bar: next }
|
||||
})
|
||||
|
||||
// Toggle item
|
||||
set((state) => {
|
||||
const next = new Set(state.bar)
|
||||
next.has(item) ? next.delete(item) : next.add(item)
|
||||
return { bar: next }
|
||||
})
|
||||
|
||||
// Clear
|
||||
set({ bar: new Set() })
|
||||
```
|
||||
|
||||
## Why New Instances?
|
||||
|
||||
Zustand detects changes by comparing references. Mutating a Map or Set doesn't change its reference:
|
||||
|
||||
```ts
|
||||
// ❌ Wrong - same reference, no re-render
|
||||
set((state) => {
|
||||
state.foo.set(key, value)
|
||||
return { foo: state.foo }
|
||||
})
|
||||
|
||||
// ✅ Correct - new reference, triggers re-render
|
||||
set((state) => ({
|
||||
foo: new Map(state.foo).set(key, value),
|
||||
}))
|
||||
```
|
||||
|
||||
## Pitfall: Type Hints for Empty Collections
|
||||
|
||||
Provide type hints when initializing empty Maps and Sets:
|
||||
|
||||
```ts
|
||||
{
|
||||
ids: new Set([] as string[]),
|
||||
users: new Map([] as [string, User][])
|
||||
}
|
||||
```
|
||||
|
||||
Without type hints, TypeScript infers `never[]` which prevents adding items later.
|
||||
|
||||
## CodeSandbox Demo
|
||||
|
||||
Basic: https://stackblitz.com/edit/vitejs-vite-5cu5ddvx
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user