SimpleR State

The simplest app state management for React

View project on GitHub

Simplifying Nested Object Updates with Proxies

When our entity is a nested object type, making deep updates the React way—no object mutations—can quickly start looking complicated. Take this entity for example:

export const items = entity([])

export const changeItemLabel = (index, label) => {
  items.set(value => [
    ...value.slice(0, index),
    { ...value[index], label },
    ...value.slice(index + 1)
  ])
}

All the action does is update the label property of an object-type item in the array. But since we're avoiding mutation of both the inner object (item) and the array, our updater function does not look as readable as we might want it to.

We can simplify this using a library like Immer (or your preferred alternative). This gives us a proxy copy of the entire nested structure which we can then safely mutate at any level of nesting.

Here's a version of the above example, this time with Immer:

import produce from 'immer'

export const items = entity([])

export const changeItemLabel = (index, label) => {
  items.set(
    produce(value => {
      value[index].label = label   // 👈 mutation allowed
    })
  )
}

Other "immutable update" libraries may have a different API from Immer, but the idea and usage remain the same.

Back to home | More recipes...