Also see React with Immer.
Immer based Reducer
const initialState = []
const reducer = produce((draft, action) => {
switch (action.type) {
case "my-action":
// use draft in here.
break
}
})
const [state, dispatch] = useReducer(reducer, initialState);
Updating an existing useReducer
If you want to use immer
for a new action, without rewriting an whole reducer:
case 'my-action': return produce(state, draft => {
// apply changes
})
Even less boilerplate
If you don’t want to write anymore boilerplate and want to just focus on writing features, you can just use zustand instead (which also solves many other common pitfalls of redux / react)
import { create } from 'zustand'
import { produce } from 'immer'
const useLushStore = create((set) => ({
lush: { forest: { contains: { a: 'bear' } } },
clearForest: () =>
set(
produce((state) => {
state.lush.forest.contains = null
}),
),
}))
const clearForest = useLushStore((state) => state.clearForest)
clearForest()
It also integrates well with Contexts and Typescript (but doesn’t require complex / long action types)