Categories
React

How to Use the useState Hook with Objects?

Spread the love

In JavaScript programs, we often have to deal with object values.

Therefore, we’ll often have to create object states and update them.

In this article, we’ll look at how to update object states in our React components.

Merging Objects

The main way to update object states with new property values is to merge the old object with new properties.

For instance, we can write:

import { useState } from "react";

export default function App() {
  const [name, setName] = useState({
    firstName: "",
    middleName: "",
    lastName: ""
  });

  return (
    <div className="App">
      <input
        value={name.firstName}
        type="text"
        onChange={(e) =>
          setName((name) => ({ ...name, firstName: e.target.value }))
        }
        name="firstName"
        placeholder="first name"
      />
      <br />
      <input
        value={name.middleName}
        type="text"
        onChange={(e) =>
          setName((name) => ({ ...name, middleName: e.target.value }))
        }
        name="middleName"
        placeholder="middle name"
      />
      <br />
      <input
        value={name.lastName}
        type="text"
        onChange={(e) =>
          setName((name) => ({ ...name, lastName: e.target.value }))
        }
        name="lastName"
        placeholder="last name"
      />
    </div>
  );
}

We have the name state which is set to an object as its initial value.

Below that, we added 3 input elements.

Each of them have the onChange prop set to a function that calls setName .

We pass a callback into the setName function that takes the name parameter, which has the current value of the name state.

And it returns an object that copies the name ‘s properties with the spread operator.

And then we set add the property that we want to change at the end of it.

It has to be at the end so that the new property overwrites the property value that already exists in the original state.

e.target.value has the inputted value.

We can also reduce repetition by creating a function that returns a function that changes the property we want.

To do this, we write:

import { useState } from "react";

export default function App() {
  const [name, setName] = useState({
    firstName: "",
    middleName: "",
    lastName: ""
  });

  const handleChange = (field) => {
    return (e) => setName((name) => ({ ...name, [field]: e.target.value }));
  };

  return (
    <div className="App">
      <input
        value={name.firstName}
        type="text"
        onChange={handleChange("firstName")}
        name="firstName"
        placeholder="first name"
      />
      <br />
      <input
        value={name.middleName}
        type="text"
        onChange={handleChange("middleName")}
        name="middleName"
        placeholder="middle name"
      />
      <br />
      <input
        value={name.lastName}
        type="text"
        onChange={handleChange("lastName")}
        name="lastName"
        placeholder="last name"
      />
    </div>
  );
}

We have the handleChange function that returns our state change functions.

It takes the field parameter, which we use as the property name by passing it into the brackets in the returned object in the setName callback.

Conclusion

We can use the useState hook with objects by passing in a callback to our state change functions that returns the copy of the existing state object and set the property to the value we want after that.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *