I am trying to update a single key value pair in an array of objets using React.
Here is the setup
An array of objects
const array = [
{id:1,name:'Tyler',age:23},
{id:2,name:'Lauren',age:28},
{id:3,name:'Nico',age:14},
]
Given an id and age, I want to be able to update the single object that matches the id. For example, given an id of 2 and age of 56, {id:2,name:'Lauren',age:28}
should change to {id:2,name:'Lauren',age:56}
My approach
I've set up useState to copy the array of object. However, I am struggling to filter out for the selected id, change the age, and return the updated array.
This is what I currently have:
import { useState } from "react";
const array = [
{ id: 1, name: "Tyler", age: 23 },
{ id: 2, name: "Lauren", age: 28 },
{ id: 3, name: "Nico", age: 14 }
];
export default function App() {
const [list, setList] = useState(array);
const updateAge = (id = 2, age = 56) => {
setList([...list, list.filter((item) => item.id === id)]);
};
return (
<>
<ul>
{list.map((item) => {
return (
<li>
{item.name} | {item.age}
</li>
);
})}
</ul>
<button onClick={updateAge}>Update age</button>
</>
);
}
Here is my codesandbox link
I am trying to update a single key value pair in an array of objets using React.
Here is the setup
An array of objects
const array = [
{id:1,name:'Tyler',age:23},
{id:2,name:'Lauren',age:28},
{id:3,name:'Nico',age:14},
]
Given an id and age, I want to be able to update the single object that matches the id. For example, given an id of 2 and age of 56, {id:2,name:'Lauren',age:28}
should change to {id:2,name:'Lauren',age:56}
My approach
I've set up useState to copy the array of object. However, I am struggling to filter out for the selected id, change the age, and return the updated array.
This is what I currently have:
import { useState } from "react";
const array = [
{ id: 1, name: "Tyler", age: 23 },
{ id: 2, name: "Lauren", age: 28 },
{ id: 3, name: "Nico", age: 14 }
];
export default function App() {
const [list, setList] = useState(array);
const updateAge = (id = 2, age = 56) => {
setList([...list, list.filter((item) => item.id === id)]);
};
return (
<>
<ul>
{list.map((item) => {
return (
<li>
{item.name} | {item.age}
</li>
);
})}
</ul>
<button onClick={updateAge}>Update age</button>
</>
);
}
Here is my codesandbox link
Share Improve this question asked Feb 7, 2022 at 17:09 Tyler MoralesTyler Morales 1,8306 gold badges29 silver badges68 bronze badges 5 |3 Answers
Reset to default 11You can use the map
function to produce a new array to set the state with.
const updateAge = (id, age) => {
console.log(id, age);
setList(
list.map((item) => {
if (item.id === id) {
return { ...item, age };
} else {
return item;
}
})
);
};
If the id matches, it will merge the new age
, otherwise it will return the item unchanged.
Note that it will only produce new objects for updated age, the rest will be the same references. That is to say it will be a new array, but most objects (except the changed one) will be the same. If you want new objects you can return { ...item }
in the else
clause as well.
In this particular case React will only be concerned that you set the state with new array.
Here's the sandbox
import { useState } from "react";
const array = [
{ id: 1, name: "Tyler", age: 23 },
{ id: 2, name: "Lauren", age: 28 },
{ id: 3, name: "Nico", age: 14 }
];
export default function App() {
const [list, setList] = useState(array);
const updateAge = (id, age) => {
// Find the item to update and store it in new list
let el = list.map((item) => {if(item.id === id){item.age=age}return
item});
// Set the previous list to the new list
setList(el)
console.log(list)
};
return (
<>
<ul>
{list.map((item, index) => {
return (
<li key={index}>
{item.name} | {item.age}
</li>
);
})}
</ul>
<button onClick={()=>updateAge(2, 56)}>Update age</button>
</>
);
}
Went to your codesandbox link changed it a bit does what you were trying to do now used Map instead of filter hope this helps
You can update you array like this
import { useState } from "react";
const array = [
{ id: 1, name: "Tyler", age: 23 },
{ id: 2, name: "Lauren", age: 28 },
{ id: 3, name: "Nico", age: 14 }
];
export default function App() {
const [list, setList] = useState(array);
const updateAge = (id = 2, age = 56) => {
setList(list.map(l=>l.id==id?{...l,age:age}:l));
};
return (
<>
<ul>
{list.map((item) => {
return (
<li>
{item.name} | {item.age}
</li>
);
})}
</ul>
<button onClick={updateAge}>Update age</button>
</>
);
}
map
instead. When the id matches, return a new object with updated age, otherwise return the same object that the map function was called with. – tromgy Commented Feb 7, 2022 at 17:17onChange
in an array of object in React Hooks. Notice how the solution is the same as classes (and the one you accepted as well)? – Emile Bergeron Commented Feb 7, 2022 at 18:22