I'm struggling to figure out what the best practice is to modify each value in an array of objects using the immutability helper.
For example, if I were to have this in my state:
this.state = {
items: [
{
name: "test",
subItems: [
{val: false}, {val: true}, {val: false}
]
},
{
name: "test2",
subItems: [
{val: true}, {val: true}, {val: false}
]
}
]
}
And I want to set every val
to false
, how might I do that.
I could do it one at a time, but there must be a better way:
let elements = update(this.state.items, {
[idx1]:{
subItems:{
[idx2]:{
val: {
$set: false
}
}
}
}
});
It certainly is possible, but it's everything but readable or understandable at first sight.
const nextState = update(state, {
items: {
$apply: (items) => {
return items.map(item => {
return update(item, {
subItems: {
$apply: (subItems) => {
return subItems.map(subItem => {
return update(subItem, {
val: {
$set: false
}
})
})
}
}
})
})
}
}
});
For an ES6 solution with immutability, destructuring and no helpers:
this.setState({
// This is if you have other state besides items.
...this.state,
items: this.state.items.map(item => ({
...item,
subItems: item.subItems.map(subItem => ({
...subItem,
val: false // or e.g. setter as a function of (item, subItem)
}))
}))
});
is easier on my eye than the update helper.
try this
this.state = {
items: [
{
name: "test",
subItems: [
{val: false}, {val: true}, {val: false}
]
},
{
name: "test2",
subItems: [
{val: true}, {val: true}, {val: false}
]
}
]
}
use functional programming
this.state.items
.filter((item) => item.name === test).subitems
.map((subItem) => {
subitem.forEach( (key) => {
{ [key]: !subitem[key] }
})
})