Points to learn about returning from immer recipe function

Akshay Jain
2 min readJul 13, 2020

Gist: -> Either return a new value *or* modify the draft

A recipe function is used to update the value in immer library, here’s an example

const recipe = draft => {
draft.cool = true;
}
const newValue = produce(recipe, {cool: false})
console.log(newValue) // { cool: true }
  1. You mutate the draft to create a newValue, returning draft after modifying it is optional, the immer will anyway return the finalized draft
  2. if you return anything else except undefined or draft from the recipe, then the new return value will replace the state
  3. Point 2 is ok, only if you do not modify the draft in your recipe function. i.e. you can choose one of the two
    a. modify the draft → return draft or undefined, either is ok
    b. want to return some new value, then don’t touch the draft at all

Now coming to the specific use case of recipe function

const badRecipe = (state, action) => state.token = action.payload.test

This function is doing two things,
1. modifying the state
2. returning action.payload.test

so it’s violating point 3 and hence will get the error from Immer library

Error: An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft

in this specific case, the intention is only to modify the state, so we have to undo the existing return with void

setToken: (state, action) => void(state.token = action.payload.test) 

However, Immer library recommends the use of code block to insure consistency across large code-base, this code block implicitly returns undefined

setToken: (state, action) => { state.token = action.payload.test }

--

--