Reputation: 3
If we have an array that contains objects that each contain and array of tags like shown below:
const arr = [
{
0: {
name: 'Apple',
tags: ['fruit', 'green']
}
},
{
1: {
name: 'ball',
tags: ['round']
}
},
{
2: {
name: 'cat',
tags: ['grey', 'meow', 'treats']
}
}
];
Is it possible to use react hooks to update the array of tags? I was trying something like this but got confused:
setArr((prev =>
([...prev,
({...prev[id],
[...prev[id]['tags'],
prev[id]['tags']: newArrOftags ]})],
));
Upvotes: 0
Views: 372
Reputation: 169
Here's the simplest syntax that I would use to target a specific item in your array, given you know the number value used within that item, and then update the previous state within your useState hook:
const lookup = 1; // Using the correct number value to target ball
const newItem = 'Additional ball tag here';
setArr((prevArr) => {
const newArr = prevArr.map((item) => {
if (item[lookup]) {
item[lookup].tags = [...item[lookup].tags, newItem];
}
return item;
});
return newArr;
});
Upvotes: 1
Reputation: 2256
Instead of using short hand syntax which is a bit complex in your case, here is what you need. I am looping through the array using map and finding the object with id. Then appending the tags to that object's tags array. In the example I am adding a few tags to an object with id 1.
let arr = [
{
0: {
name: 'Apple',
tags: ['fruit', 'green']
}
},
{
1: {
name: 'ball',
tags: ['round']
}
},
{
2: {
name: 'cat',
tags: ['grey', 'meow', 'treats']
}
}
];
const id = 1;
const tags = ["test1","test2","test3"]
arr = arr.map((a)=>{
if(Object.keys(a).includes(id.toString()))
{
a[id].tags = [...a[id].tags,...tags];
}
return a;
})
Use the above logic instead of spread operator to set state. map
returns a new array so it's safe to use for state updates.
Here is an example of the logic: https://stackblitz.com/edit/js-xqnjai
Upvotes: 0