动态 Table 更新 "too late" ReactJS

Dynamic Table updates "too late" ReactJS

我的问题是,我有一个 table,它应该在用户每次从下拉组件中选择内容时更新。现在的问题是我的 table 在前端更新“太晚了”。因此,当用户第一次选择一个选项时,什么也不会发生。然后当用户第二次从下拉组件中选择一个选项时, table 将显示他之前选择的选项的数据。如果用户第 3 次选择一个选项,table 将显示第二次的数据,依此类推。 那么我该如何解决呢?我使用 ReactJS 和语义 UI

我的代码: 这将呈现现有数据的行

renderTableData() {
    return this.state.songs.map((song, index) => {
       const { id, nr, songname, link } = song 
       return (
          <Table.Row key={id}>
             <Table.Cell>{nr}</Table.Cell>
             <Table.Cell>{songname}</Table.Cell>
             <Table.Cell>{link}</Table.Cell>
          </Table.Row>
       )
    })
 }

React 的主要 render() 函数中的代码(显示正确,希望数据“过时”:

    `<Table>
       <Table.Header>
           <Table.Row>
              <Table.HeaderCell width={1}>Nr</Table.HeaderCell>
              <Table.HeaderCell width={2}>Songname</Table.HeaderCell>
              <Table.HeaderCell width={1}>Link</Table.HeaderCell>
           </Table.Row>
       </Table.Header>
       {this.renderTableData()}
    </Table>`

下拉选项更改时的代码:

onChangeDropdown(e) {
  this.setState({game: e.target.textContent}, ()=>{
    this.state.songs.length = 0;
      for(var i = 0; i< this.state.musicData.length;i++){
        if(this.state.musicData[i].game == this.state.game){
          for(var j = 0; j<this.state.musicData[i].songs.length;j++){
            this.state.songs.push({id: j+1, nr: j+1, songname: this.state.musicData[i].songs[j].name, link: this.state.musicData[i].songs[j].link})
          }
          break;
        }
      }
      this.renderTableData()
  })
}

this.setState 中的游戏变量是正确的,并且当用户更改下拉选项时 for 循环也按预期工作,我已经用调试器检查过了

我希望你能帮助我,ty

不是更新太晚了,而是你在不使用 setState 的情况下改变状态,所以 React 不知道发生了什么变化,你应该重构你的代码以始终使用 setState 来更新状态,而不是 push,像这样:

onChangeDropdown(e) {
  this.setState((currentState) => {
    const newSongs = [];
    const game = e.target.textContent;

    musicData.forEach((data) => {
      if (data.game === game) {
        musicData.songs.forEach((song, index) => {
          newSongs.push({
            id: index + 1,
            nr: index + 1,
            songname: song.name,
            link: song.link,
          });
        });
      }
    });

    return {
      ...currentState,
      game,
      songs: newSongs,
    };
  });
}

我将您的 for 循环更改为使用 forEach,复杂性更低,更易于阅读

这是我所做的:

  • 创建一个空数组来存储所选歌曲(newSongs)
  • 循环播放所有音乐数据,然后循环播放音乐数据中每个项目中的所有歌曲
  • 将所选游戏中的歌曲添加到newSongs
  • return newSongs + game更新选中的游戏,...currentState是保留变化之间的其他部分状态

所以每次下拉列表发生变化时,我都会创建一个新数组和运行逻辑

setState回调可以return一个对象来替换整个状态,所以在此之前你可以做任何你需要的计算。

在 React 中更新状态是异步的,这是您不能直接改变状态并且需要在需要更新时使用 setState 的原因之一