Reputation: 1829
I have an array of objects saved in state and each of the objects in the array has another array on objects.
here is an example of a single object:
id : uuid.v1(),
area : 'Scratch',
name : 'Untitled',
status : "",
size : "",
created : {
name : "username",
time : new Date()
},
modified : {
name : "username",
time : new Date()
},
content: [{
id : uuid.v1(),
Content : "Content 1",
TowerRed : "",
TowerText : "text"
},
{
id : uuid.v1(),
Content : "Content 2",
TowerRed : "",
TowerText : "text"
}]
I need to be able to remove an object from inside the content array inside of these objects.
For example I need to remove the object containing 'content 1' without modifying the object containing 'content 2'
I have tried to use the react immutability helpers her but with no success.
here I loop through the parent objects and the content objects until I find a match with the 'itemID' (itemID) is the id of the object i want to remove form the content array.
var tickerIndex = null;
var tickerItemIndex = null;
for (var i = 0; i < this.state.scratchTickers.length; i++) {
var tickersContent = this.state.scratchTickers[i].content;
tickerIndex = i;
for (var x = 0; x < tickersContent.length; x++) {
if (tickersContent[x].id == itemID) {
tickerItemIndex = x;
}
}
}
then I create a reference to the parent object and its content array:
var item = this.state.scratchTickers[tickerIndex].content;
Finally I use the update immuatbility help to splice the array and remove the correct object based on its itemID:
this.setState ({
scratchTickers: update(item, {
$splice: [[tickerItemIndex, 1]]
})
})
But this just doesn't seem to work.
here is the whole function:
_deleteTickerItem: function(itemID) {
var tickerIndex = null;
var tickerItemIndex = null;
for (var i = 0; i < this.state.scratchTickers.length; i++) {
var tickersContent = this.state.scratchTickers[i].content;
tickerIndex = i;
for (var x = 0; x < tickersContent.length; x++) {
if (tickersContent[x].id == itemID) {
tickerItemIndex = x;
}
}
}
var item = this.state.scratchTickers[tickerIndex].content;
this.setState ({
scratchTickers: update(item, {
$splice: [[tickerItemIndex, 1]]
})
})
},
Upvotes: 1
Views: 4151
Reputation: 634
It looks like your setState
call is overriding your scratchTickers
data with just the value of one particular scratchTicker
's content
.
What you're essentially trying to do is map your array of scratchTickers
to a new array with filtered content.
_deleteTickerItem: function(itemID) {
this.setState({
scratchTickers: this.state.scratchTickers.map(scratchTicker =>
Object.assign({}, scratchTicker, {
content: scratchTicker.content.filter(content => content.id != itemID)
})
)
});
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
Update:
When rendering, make sure if you're using an iterator that you're not using the array indices as keys, like this.
// bad
{content.map((content, index) =>
<p key={index}>{content.Content}</p>
)}
When React diffs with the virtual DOM on a change, it will look at the keys to determine what has changed. So if you're using indices and there is one less in the array, it will remove the last one. Instead, use the id
's of the content
as keys, like this.
// good
{content.map(content =>
<p key={content.id}>{content.Content}</p>
)}
Upvotes: 1