No Time Dad

A blog about web development written by a busy dad

React useState Object Update Example

It always suprising to me how far I can go in building a React application without needing to set state values. I do, however usually end up needing to create a state object of some kind somewhere in the process. That state object always needs to be updated. Otherwise I wouldn’t store it in state.

I wrote previously about using React’s useState hook to update an array of objects, so I thought it’d be a good idea to also cover the case where the state value is an object with specific keys that need to be updated. Which is very common.

// package.json
...
"react": "^17.0.2",
...
import React, { useState } from 'react';

export const InputUpdate = () => {
  const [state, setState] = useState({ name: 'notimedad', password: '' });
  
  const handleNameChange = (event) => setState({
    ...state,
    name: event.target.value,
  });

  const handlePasswordChange = (event) => setState({
    ...state,
    password: event.target.value,
  });

  const handleSubmit = () => console.log('submit!');

  return (
    <div>
      <form>
        <p>
          <label for="name">Name</label>
          <input id="name" value={state.name} onChange={handleNameChange} />
        </p>
        <p>
          <label for="password">Password</label>
          <input id="password" value={state.password} onChange={handlePasswordChange} />
        </p>
        <button onClick={handleSubmit} type="button">Sign in</button>
      </form>
    </div>
  )
}

The example above is a sign-in form that contains two inputs that map to keys in a state object. When the user types into either input field, the component state should be updated with the new value. This is done by calling either change function via React’s onChange attribute.

const handleNameChange = (event) => setState({
  ...state,
  name: event.target.value,
});

The important thing to note here is that this React useState object update is not modifying the existing state directly, but instead it’s using the spread operator to create a copy the existing state values into a new object. Once the existing values are copied over, I can then target specific keys in the object, like name, that I want to update with new values.

Nothing is stopping me from modifying the existing state directly, but it’s considered best practice in React to treat the state as immutable. Which is why this useState object update example creates a new object with updated values.