Objects in State

You cannot mutate (modify an objects contents) objects, since they are reference types and the reference will not update. Reacts state will not change and therefore, no update render will get called.

const [position, setPosition] = useState({ x: 0, y: 0 });
position.x = 5;

// NOTHING WILL UPDATE

Replace the Object

Instead treat objects in state as immutable and create a replacement each time you wanna update it.

setPosition({
  x: position.clientX,
  y: position.clientY
});

// or use the spread operator

setPerson({
  ...person, // Copy the old fields
  firstName: e.target.value // But override this one
});

Updating nested objects

When you wanna update a nested object, things can become messy.

setPerson({
  ...person, // Copy other fields
  artwork: { // but replace the artwork
    ...person.artwork, // with the same one
    city: 'New Delhi' // but in New Delhi!
  }
});

So instead use Immer. This allows you to modify just certain fields.

npm install use-immer

import { useState } from 'react'

const [person, updatePerson] = useImmer({
  name: 'Niki de Saint Phalle',
  artwork: {
    title: 'Blue Nana',
    city: 'Hamburg',
    image: 'https://i.imgur.com/Sd1AgUOm.jpg',
  }
});

updatePerson(draft => {
  draft.name = e.target.value;
});