【问题标题】:How to correctly change state of a multiple nested array of objects in React?如何正确更改 React 中多个嵌套对象数组的状态?
【发布时间】:2019-05-29 23:03:25
【问题描述】:

在 React 中更改多个嵌套对象数组的状态的最佳方法是什么?让我们看看下面的例子:我有一个组件,它将显示每个流派的顶级播放列表。我有一个属性 genre ,它是一个对象数组,每个对象都有一个属性 songs ,它也是一个对象数组。如果我想及时将名为 Soldier of Fortune 的歌曲更改为 Child(假设在 Change 函数中作为参数,我已经从 UI 更改中提供了 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?
  }

【问题讨论】:

  • 这可能含糊不清,但是如何不使用 map (我假设你使用 map :D )使用 for 循环或 while 你可以将数组的索引存储为组件适当性?
  • 我只是对更新状态感到好奇,而不是显示数据。假设我已经显示了所有内容,并且我有一个输入字段,其中包含数据列表,并且我得到了正确的歌曲索引和流派索引。我只需要弄清楚如何正确更改状态

标签: javascript reactjs react-native setstate


【解决方案1】:

您可以将您的 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
})

}

【讨论】:

  • 这有点用,但是在输入字段中键入一个字母后,我失去了焦点。所以,我需要再次点击并再输入一个字母,以此类推
  • 在按下按钮时更新这些更改是一个很好的做法。不是在更改 textInput 上的值时。单独处理您的 textInput。
  • 另外我能知道您使用什么组件进行输入以及您是如何实现的吗?
  • 我使用了来自“reactstrap”模块的输入。我正在映射元素的数组,然后是 onChange,我正在发送一个事件,什么类型是什么,我正在改变什么歌曲。像这样的东西。 {handleChange(e,genreIndex, songIndex, )}} />
  • 我正在研究 react-native 的简单 TextInput 组件。我认为你实现它是正确的,但我不知道触发键时突然失焦的原因。但是在我对您的主要问题的回答中。这是更改嵌套对象状态的最佳方法之一。
【解决方案2】:

我会这样改变你的状态:

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

  }

【讨论】:

  • 我认为这会改变状态,因为我正在直接处理它的值?
  • 是的,你是对的。您应该创建流派的深层副本,而不是在设置新状态之前进行操作。我更新了答案。
猜你喜欢
  • 2020-12-08
  • 2019-08-28
  • 1970-01-01
  • 2019-12-14
  • 2020-04-01
  • 2021-05-23
  • 2020-11-13
  • 2018-07-04
  • 1970-01-01
相关资源
最近更新 更多