Using produce

egghead.io lesson 3: Simplifying deep updates with _produce_
Hosted on egghead.io

The Immer package exposes a default function that does all the work.

produce(currentState, producer: (draftState) => void): nextState

There is also a curried overload that is explained in a later section.

Example#

import produce from "immer"
const baseState = [
{
todo: "Learn typescript",
done: true
},
{
todo: "Try immer",
done: false
}
]
const nextState = produce(baseState, draftState => {
draftState.push({todo: "Tweet about it"})
draftState[1].done = true
})

The interesting thing about Immer is that the baseState will be untouched, but the nextState will reflect all changes made to draftState.

// the new item is only added to the next state,
// base state is unmodified
expect(baseState.length).toBe(2)
expect(nextState.length).toBe(3)
// same for the changed 'done' prop
expect(baseState[1].done).toBe(false)
expect(nextState[1].done).toBe(true)
// unchanged data is structurally shared
expect(nextState[0]).toBe(baseState[0])
// changed data not (dûh)
expect(nextState[1]).not.toBe(baseState[1])