Как лучше всего изменить состояние нескольких вложенных массивов объектов в React? Давайте посмотрим на пример ниже: у меня есть компонент, который будет отображать список воспроизведения для каждого жанра. У меня есть свойство жанр , которое представляет собой массив объектов, и у каждого объекта есть свойство song , которое также является массивом объектов. Если я хочу изменить песню с именем Soldier of Fortune на Child in Time (допустим, в функции Change в качестве параметров у меня есть индексы Song и Genre, уже предоставленные из изменения пользовательского интерфейса). Как я могу получить доступ к нескольким уровням вложенных объектов и не изменять их состояние?

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?
  }

1
Amel Amcë Muminovic 30 Май 2019 в 02:03

2 ответа

Лучший ответ

Вы можете изменить свою функцию handleChangeSongName следующим образом:

  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
})

}

1
Mervzs 30 Май 2019 в 00:10

Я бы изменил ваше состояние так:

this.state = {
      title: "Top playlists",
      genres: [
        {
          followers: 2456,
          genreName: "pop",
          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?

    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
        });
     }

  }
0
Mitro 30 Май 2019 в 00:08