Using Immer
immerPage.why.title
immerPage.why.description
// Without Immer - verbose and error-prone
set((state) => ({
...state,
nested: {
...state.nested,
deep: {
...state.nested.deep,
value: newValue
}
}
}))
// With Immer - simple and intuitive
set((state) => {
state.nested.deep.value = newValue
})immerPage.installation.title
npm install immer
# or
yarn add immer
# or
pnpm add immerimmerPage.basicUsage.title
immerPage.basicUsage.description
import { create } from 'zustand'
import { immer } from 'zustand/middleware/immer'
const useStore = create(
immer((set) => ({
todos: [],
addTodo: (todo) => set((state) => {
state.todos.push(todo)
}),
toggleTodo: (id) => set((state) => {
const todo = state.todos.find((t) => t.id === id)
if (todo) {
todo.completed = !todo.completed
}
}),
deleteTodo: (id) => set((state) => {
const index = state.todos.findIndex((t) => t.id === id)
if (index !== -1) {
state.todos.splice(index, 1)
}
}),
}))
)immerPage.nestedState.title
immerPage.nestedState.description
const useStore = create(
immer((set) => ({
user: {
profile: {
name: 'John',
settings: {
theme: 'light',
notifications: {
email: true,
push: false,
},
},
},
},
toggleEmailNotifications: () => set((state) => {
state.user.profile.settings.notifications.email =
!state.user.profile.settings.notifications.email
}),
setTheme: (theme) => set((state) => {
state.user.profile.settings.theme = theme
}),
}))
)immerPage.combining.title
immerPage.combining.description
import { create } from 'zustand'
import { devtools, persist } from 'zustand/middleware'
import { immer } from 'zustand/middleware/immer'
const useStore = create(
devtools(
persist(
immer((set) => ({
todos: [],
addTodo: (todo) => set((state) => {
state.todos.push(todo)
}),
})),
{ name: 'todo-storage' }
),
{ name: 'TodoStore' }
)
)immerPage.typescript.title
import { create } from 'zustand'
import { immer } from 'zustand/middleware/immer'
interface Todo {
id: string
text: string
completed: boolean
}
interface TodoState {
todos: Todo[]
addTodo: (todo: Todo) => void
toggleTodo: (id: string) => void
}
const useStore = create<TodoState>()(
immer((set) => ({
todos: [],
addTodo: (todo) => set((state) => {
state.todos.push(todo)
}),
toggleTodo: (id) => set((state) => {
const todo = state.todos.find((t) => t.id === id)
if (todo) {
todo.completed = !todo.completed
}
}),
}))
)