Last updated: Apr 6, 2024
Reading timeยท7 min
To update an object in an array in React state:
map()
method to iterate over the array.import {useState} from 'react'; const App = () => { const initialState = [ {id: 1, country: 'Austria'}, {id: 2, country: 'Belgium'}, {id: 3, country: 'Canada'}, ]; const [data, setData] = useState(initialState); const updateState = () => { const newState = data.map(obj => { // ๐๏ธ if id equals 2, update country property if (obj.id === 2) { return {...obj, country: 'Denmark'}; } // ๐๏ธ otherwise return the object as is return obj; }); setData(newState); }; return ( <div> <button onClick={updateState}>Update state</button> {data.map(obj => { return ( <div key={obj.id}> <h2>id: {obj.id}</h2> <h2>country: {obj.country}</h2> <hr /> </div> ); })} </div> ); }; export default App;
The function we passed to the Array.map() method gets called with each element (object) in the array.
Whatever we return from the function we passed to the map()
method gets
inserted into the new array.
map()
method doesn't mutate the original array, it returns a new array.On each iteration, we check if the object has an id
property equal to 2
.
const updateState = () => { const newState = data.map(obj => { // ๐๏ธ If id equals 2, update country property if (obj.id === 2) { return {...obj, country: 'Denmark'}; } // ๐๏ธ Otherwise return the object as is return obj; }); setData(newState); };
If it does, we use the
spread operator (...)
to unpack the other key-value pairs of the object and then we override the
country
property.
If the condition isn't met, we return the object as is.
setState
method to update a component's state, it's easier for React to track changes and re-render only what's necessary.The second object in the state array gets updated when I click on the button.
setState
methodYou can also pass a function to the setState
method that we get from the
useState hook.
The function gets called with the current state and can be used to update a specific object in the state array.
import {useState} from 'react'; const App = () => { const initialState = [ {id: 1, country: 'Austria'}, {id: 2, country: 'Belgium'}, {id: 3, country: 'Canada'}, ]; const [data, setData] = useState(initialState); const updateState = () => { // ๐๏ธ Passing a function to the setData method setData(prevState => { const newState = prevState.map(obj => { // ๐๏ธ If id equals 2, update country property if (obj.id === 2) { return {...obj, country: 'Denmark'}; } // ๐๏ธ Otherwise return the object as is return obj; }); return newState; }); }; return ( <div> <button onClick={updateState}>Update state</button> {data.map(obj => { return ( <div key={obj.id}> <h2>id: {obj.id}</h2> <h2>country: {obj.country}</h2> <hr /> </div> ); })} </div> ); }; export default App;
The code sample achieves the same result.
However, this time we passed a function directly to the setData
method. The
function gets called with the current state which we can use to calculate the
next state.
const updateState = () => { // ๐๏ธ Passing a function to the setData method setData(prevState => { const newState = prevState.map(obj => { // ๐๏ธ if id equals 2, update the country property if (obj.id === 2) { return {...obj, country: 'Denmark'}; } // ๐๏ธ otherwise return the object as is return obj; }); return newState; }); };
Whatever we return from the callback function gets set as the new state.
To update an array of objects state in React:
map()
method to iterate over the array.import {useState} from 'react'; export default function App() { const initialState = [ {id: 1, name: 'Alice', country: 'Austria'}, {id: 2, name: 'Bob', country: 'Belgium'}, ]; const [employees, setEmployees] = useState(initialState); // โ Add an object to a state array const addObjectToArray = obj => { setEmployees(current => [...current, obj]); }; // โ Update one or more objects in a state array const updateObjectInArray = () => { setEmployees(current => current.map(obj => { if (obj.id === 2) { return {...obj, name: 'Sophia', country: 'Sweden'}; } return obj; }), ); }; // โ Remove one or more objects from the state array const removeObjectFromArray = () => { setEmployees(current => current.filter(obj => { return obj.id !== 2; }), ); }; return ( <div> <button onClick={() => addObjectToArray({ id: Math.random(), name: 'Carl', country: 'Canada', }) } > Add employee </button> <button onClick={updateObjectInArray}>Update object in array</button> <button onClick={removeObjectFromArray}>Remove object from array</button> {employees.map(employee => { return ( <div key={employee.id}> <h2>name: {employee.name}</h2> <h2>country: {employee.country}</h2> <hr /> </div> ); })} </div> ); }
The examples show how to:
To add an object to a state array, we have to use the spread syntax (...) to unpack the elements of the array and add the object at the end.
const addObjectToArray = obj => { setEmployees(current => [...current, obj]); }; addObjectToArray({ id: 3, name: 'Carl', country: 'Canada', })
We passed a function to setState
because it is guaranteed to be called with
the current (most up-to-date) state.
To update an object in a state array, call the map()
method to iterate over
the array and update the object that matches the condition.
const updateObjectInArray = () => { setEmployees(current => current.map(obj => { if (obj.id === 2) { return {...obj, name: 'Sophia', country: 'Sweden'}; } return obj; }), ); };
The function we passed to the Array.map() method gets called with each element in the array.
On each iteration, we check if the id
of the object is equal to 2
, and if it
is, we update its name
and country
properties.
Otherwise, we return the object as is.
We can use the Array.filter() method to remove an object from a state array in React.
const removeObjectFromArray = () => { setEmployees(current => current.filter(obj => { return obj.id !== 2; }), ); };
The function we passed to the filter
method gets called with each element in
the array.
On each iteration, we check if the object doesn't have an id
equal to 2
and
return the result.
The filter
method returns a new array containing only the truthy values that
the callback function returned.
To replace an object in an array in the state:
map()
method to iterate over the array.import {useState} from 'react'; const App = () => { const initialState = [ {id: 1, country: 'Austria'}, {id: 2, country: 'Belgium'}, {id: 3, country: 'Canada'}, ]; const [data, setData] = useState(initialState); const updateState = () => { const newState = data.map(obj => { // ๐๏ธ If id equals 2 replace object if (obj.id === 2) { return {id: 1234, country: 'Germany'}; } // ๐๏ธ Otherwise return the object as is return obj; }); setData(newState); }; return ( <div> <button onClick={updateState}>Update state</button> {data.map(obj => { return ( <div key={obj.id}> <h2>id: {obj.id}</h2> <h2>country: {obj.country}</h2> <hr /> </div> ); })} </div> ); }; export default App;
The function we passed to the Array.map() method gets called with each element (object) in the array.
Whatever we return from the function we passed to the map()
method gets
inserted into the new array.
map()
method does not mutate the original array, it returns a new array.On each iteration, we check if the object has an id
property that equals 2
.
If it does, we replace it with a new object.
If the condition is not met, we return the object as is.
If I click on the button, the second object in the state array gets replaced.
Note that you can also update only certain properties on the object in your state array.
import {useState} from 'react'; const App = () => { const initialState = [ {id: 1, country: 'Austria'}, {id: 2, country: 'Belgium'}, {id: 3, country: 'Canada'}, ]; const [data, setData] = useState(initialState); const updateState = () => { const newState = data.map(obj => { // ๐๏ธ If id equals 2, update country property if (obj.id === 2) { return {...obj, country: 'Denmark'}; } // ๐๏ธ Otherwise return the object as is return obj; }); setData(newState); }; return ( <div> <button onClick={updateState}>Update state</button> {data.map(obj => { return ( <div key={obj.id}> <h2>id: {obj.id}</h2> <h2>country: {obj.country}</h2> <hr /> </div> ); })} </div> ); }; export default App;
The code snippet above is very similar to the previous one. However, instead of
replacing the entire object, we override the country
property and use the
spread syntax (...)
to copy over the rest of the properties.
This is useful when you don't need to replace the entire object and need to only update some of the object's properties.
I've also written an article on how to update nested properties in a state object.
You can learn more about the related topics by checking out the following tutorials: