Update nested properties in a State object in React

avatar
Borislav Hadzhiev

Last updated: Jan 17, 2023
2 min

banner

# Update nested properties in a State object in React

To update nested properties in a state object in React:

  1. Pass a function to setState to get access to the current state object.
  2. Use the spread syntax (...) to create a shallow copy of the object and the nested properties.
  3. Override the properties you need to update.
App.js
import {useState} from 'react'; export default function App() { const initialState = { name: 'Alice', address: { country: 'Austria', coords: [1, 2], }, }; const [employee, setEmployee] = useState(initialState); const updateNestedProps = () => { setEmployee(current => { // ๐Ÿ‘‡๏ธ using spread syntax (...) return { ...current, address: { ...current.address, // ๐Ÿ‘‡๏ธ override value for nested country property country: 'Germany', }, }; }); }; return ( <div> <button onClick={updateNestedProps}>Click</button> <h4>{JSON.stringify(employee, null, 4)}</h4> </div> ); }

update nested state property

We used the spread syntax (...) to unpack the key-value pairs of the objects into a new object creating shallow copies.

App.js
const employee = { name: 'Alice', address: { country: 'Austria', coords: [1, 2], }, }; const newEmployee = { ...employee, address: { ...employee.address, // ๐Ÿ‘‡๏ธ override country property country: 'Germany', }, }; // ๐Ÿ‘‡๏ธ newEmployee.address.country is 'Germany' now console.log(newEmployee);

Notice that we aren't directly mutating the state object in any way.

We are unpacking the key-value pairs of the state object into a new object and overriding the properties we want to update.

The country property overrides the property with the same name that exists on the object because we provided it after using the spread syntax.

We passed a function to setState because the function is guaranteed to be invoked with the current (most up-to-date) state.

App.js
const updateNestedProps = () => { setEmployee(current => { // ๐Ÿ‘‡๏ธ using spread syntax (...) return { ...current, address: { ...current.address, // ๐Ÿ‘‡๏ธ override value for nested country property country: 'Germany', }, }; }); };

When the next state is computed using the previous state, pass a function to setState.

Otherwise, we might get some weird race condition if the state object we have access to does not represent the most up-to-date value.

If you get the warning prop spreading is forbidden, click on the link and follow the instructions.

# Update nested properties in a State object by creating a copy

Alternatively, you can create a copy of the nested object and directly update the property on the copy.

App.js
import {useState} from 'react'; export default function App() { const initialState = { name: 'Alice', address: { country: 'Austria', coords: [1, 2], }, }; const [employee, setEmployee] = useState(initialState); const updateNestedProps = () => { setEmployee(current => { // ๐Ÿ‘‡๏ธ get copy of nested object const address = {...current.address}; address.country = 'Germany'; return {...current, address}; }); }; return ( <div> <button onClick={updateNestedProps}>Click</button> <h4>{JSON.stringify(employee, null, 4)}</h4> </div> ); }

update nested state property

This example achieves the same result, however, is a bit more difficult to read and a bit more tricky.

We created a copy of the state.address object and directly updated the country property on the copy.

Then we set the address property in the new state object to the copy we updated.

Which approach you pick is a matter of personal preference. I'd go with the first example because it is much more intuitive to simply override the properties we want to update.

I've also written an article on how to update a component's state on click.

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev