What would be the best way to change the state of multiple nested arrays of objects in React? Let's see the example below: I have a ponent that will display the top playlist for each genre. I have a property genre which is an array of objects and each object has a property songs which is also an array of objects. If I want to change the song named Soldier of Fortune to Child in Time (Let's suppose in Change function as parameters I have indexes of Song and Genre already provided from the UI change). How can I access multiple levels of nested objects and not mutate the state?
this.state = {
title: 'Top playlists',
genres: [
{
genreName: 'pop',
followers: 2456,
songs: [
{
title: 'Soldier of fortune',
author: 'Deep Purple',
},
],
},
],
};
handleChangeSongName = (e, genreIndex, songIndex) => {
// genreIndex = 0;
// songIndex = 0;
// e.target.name = title;
// e.target.value = "Child in time"
...What to do here?
}
What would be the best way to change the state of multiple nested arrays of objects in React? Let's see the example below: I have a ponent that will display the top playlist for each genre. I have a property genre which is an array of objects and each object has a property songs which is also an array of objects. If I want to change the song named Soldier of Fortune to Child in Time (Let's suppose in Change function as parameters I have indexes of Song and Genre already provided from the UI change). How can I access multiple levels of nested objects and not mutate the state?
this.state = {
title: 'Top playlists',
genres: [
{
genreName: 'pop',
followers: 2456,
songs: [
{
title: 'Soldier of fortune',
author: 'Deep Purple',
},
],
},
],
};
handleChangeSongName = (e, genreIndex, songIndex) => {
// genreIndex = 0;
// songIndex = 0;
// e.target.name = title;
// e.target.value = "Child in time"
...What to do here?
}
Share
Improve this question
edited May 30, 2019 at 0:00
Amel Amcë Muminovic
asked May 29, 2019 at 23:03
Amel Amcë MuminovicAmel Amcë Muminovic
4571 gold badge8 silver badges21 bronze badges
2
- This may be vague, but how about instead of using map ( I assumed u used map :D ) use a for loop or a while in which you can store the index of you'r array's as a ponent propriety ? – Ionut Eugen Commented May 29, 2019 at 23:43
- I am just curious about updating the state, not displaying the data. Let's suppose I have displayed everything and I have an input field where you have the list of the data and I got the correct index of song and index of the genre. I just need to figure out how to properly change the state – Amel Amcë Muminovic Commented May 29, 2019 at 23:50
2 Answers
Reset to default 4you can modify your handleChangeSongName function to this:
handleChangeSongName = (e, genreIndex, songIndex) => {
// genreIndex = 0;
// songIndex = 0;
// e.target.name = title;
// e.target.value = "Child in time"
this.setState((prevState) => {
let temp = {
...prevState,
genres: [...prevState.genres]
}
// change title "Soldier of fortune" to "Child in time"
temp.genres[genreIndex].songs[songIndex][e.target.name] = e.target.value
return temp
})
}
I would change your state like this:
this.state = {
title: "Top playlists",
genres: [
{
followers: 2456,
genreName: "pop",
songs: [
{
title: "Soldier of fortune",
author: "Deep Purple"
}
]
}
]
};
and then
handleChangeSongName = (e, genreIndex, songIndex) => {
// genreIndex = 0;
// songIndex = 0;
// e.target.name = title;
// e.target.value = "Child in time"
...What to do here?
const genres = _.cloneDeep(this.state.genres); // create deep copy with underscore
// or like this
// const genres = JSON.parse(JSON.stringify(this.state.genres))
if(genres.length && genres[genreIndex] && genres[genreIndex].songs.length && genres[genreIndex].songs[songIndex]) {
genres[genreIndex].songs[songIndex][e.target.name] = e.target.value;
this.setState({
genres: genres
});
}
}