Table of Contents
In my previous article, I have explained how to store and update arrays in useState hook. In this article, we will see how to modify the objects stored using the useState hook.
Project Setup
Create a react project using the following command:
1npx create-react-app react-usestate-object
Updating the state object
Let's create 2 fields with firstName
and lastName
:
1import { useState } from "react"23function App() {4 const [name, setName] = useState({ firstName: "", lastName: "" })56 return (7 <div className="App">8 <div>9 <label htmlFor="firstName">First Name: </label>10 <input11 type="text"12 name="firstName"13 id="firstName"14 value={name.firstName}15 />16 </div>17 <div>18 <label htmlFor="lastName">Last Name: </label>19 <input20 type="text"21 name="lastName"22 id="lastName"23 value={name.lastName}24 />25 </div>26 <div>27 Name is: {name.firstName} {name.lastName}28 </div>29 </div>30 )31}3233export default App
Here we have the name
object as the local state to store the firstName
and lastName
. Currently, these fields are read-only.
Let's go ahead and add onChange
functions to these fields and update the state object when the users type in the input field:
1import { useState } from "react"23function App() {4 const [name, setName] = useState({ firstName: "", lastName: "" })56 const setFirstName = e => {7 setName(existingValues => ({8 // Retain the existing values9 ...existingValues,10 // update the firstName11 firstName: e.target.value,12 }))13 }1415 const setLastName = e => {16 setName(existingValues => ({17 // Retain the existing values18 ...existingValues,19 // update the lastName20 lastName: e.target.value,21 }))22 }2324 return (25 <div className="App">26 <div>27 <label htmlFor="firstName">First Name: </label>28 <input29 type="text"30 name="firstName"31 id="firstName"32 value={name.firstName}33 onChange={setFirstName}34 />35 </div>36 <div>37 <label htmlFor="lastName">Last Name: </label>38 <input39 type="text"40 name="lastName"41 id="lastName"42 value={name.lastName}43 onChange={setLastName}44 />45 </div>46 <div>47 Name is: {name.firstName} {name.lastName}48 </div>49 </div>50 )51}5253export default App
Here, we make use of the spread operator to retain the existing values and update only the required values.
Combining the update to a single function
Since the functionality in updating both the fields are same, we can write a common update function as shown below:
1import { useState } from "react"23function App() {4 const [name, setName] = useState({ firstName: "", lastName: "" })56 const updateName = e => {7 const fieldName = e.target.name8 setName(existingValues => ({9 // Retain the existing values10 ...existingValues,11 // update the current field12 [fieldName]: e.target.value,13 }))14 }1516 return (17 <div className="App">18 <div>19 <label htmlFor="firstName">First Name: </label>20 <input21 type="text"22 name="firstName"23 id="firstName"24 value={name.firstName}25 onChange={updateName}26 />27 </div>28 <div>29 <label htmlFor="lastName">Last Name: </label>30 <input31 type="text"32 name="lastName"33 id="lastName"34 value={name.lastName}35 onChange={updateName}36 />37 </div>38 <div>39 Name is: {name.firstName} {name.lastName}40 </div>41 </div>42 )43}4445export default App
Here we have used [variableContainingPropertyName]
notation to set the appropriate object value.
If there are many fields, you can make use of the useReducer hook, which helps for form validation as well.
Do follow me on twitter where I post developer insights more often!
Leave a Comment