Returning new data from producers
It is not needed to return anything from a producer, as Immer will return the (finalized) version of the draft
anyway. However, it is allowed to just return draft
.
It is also allowed to return arbitrarily other data from the producer function. But only if you didn't modify the draft. This can be useful to produce an entirely new state. Some examples:
Note: It is not possible to return undefined
this way, as it is indistinguishable from not updating the draft! Read on...
undefined
using nothing
#
Producing So, in general, one can replace the current state by just return
ing a new value from the producer, rather than modifying the draft. There is a subtle edge case however: if you try to write a producer that wants to replace the current state with undefined
:
Versus:
The problem is that in JavaScript a function that doesn't return anything also returns undefined
! So immer cannot differentiate between those different cases. So, by default, Immer will assume that any producer that returns undefined
just tried to modify the draft.
However, to make it clear to Immer that you intentionally want to produce the value undefined
, you can return the built-in token nothing
:
N.B. Note that this problem is specific for the undefined
value, any other value, including null
, doesn't suffer from this issue.
Tip: to be able to return nothing
from a recipe when using TypeScript, the state
's type must accept undefined
as value.
void
#
Inline shortcuts using Draft mutations in Immer usually warrant a code block, since a return denotes an overwrite. Sometimes that can stretch code a little more than you might be comfortable with.
In such cases, you can use javascripts void
operator, which evaluates expressions and returns undefined
.
Code style is highly personal, but for code bases that are to be understood by many, we recommend to stick to the classic draft => { draft.user.age += 1}
to avoid cognitive overhead.