Curried producers

egghead.io lesson 6: Simplify code by using curried _reduce_
Hosted on egghead.io

Passing a function as the first argument to produce creates a function that doesn't apply produce yet to a specific state, but rather creates a function that will apply produce to any state that is passed to it in the future. This generally is called currying. Take for example the following example:

import produce from "immer"
function toggleTodo(state, id) {
return produce(state, draft => {
const todo = draft.find(todo => todo.id === id)
todo.done = !todo.done
})
}
const baseState = [
{
id: "JavaScript",
title: "Learn TypeScript",
done: true
},
{
id: "Immer",
title: "Try Immer",
done: false
}
]
const nextState = toggleTodo(baseState, "Immer")

The above pattern of toggleTodo is quite typical; pass an existing state to produce, modify the draft, and then return the result. Since state isn't used for anything else than passing it on to produce, the above example can be simplified by using the curried form of produce, where you pass produce only the recipe function, and produce will return a new function that will apply recipe to the base state. This allows us to shorten the above toggleTodo definition.

import produce from "immer"
// curried producer:
const toggleTodo = produce((draft, id) => {
const todo = draft.find(todo => todo.id === id)
todo.done = !todo.done
})
const baseState = [
/* as is */
]
const nextState = toggleTodo(baseState, "Immer")

Note that the id param has now become part of the recipe function! This pattern of having curried producers combines really neatly with for example the useState hook from React, as we will see on the next page.