我如何在React状态下更新数组内部的对象属性的值

时间:2019-04-12 12:36:05

标签: javascript reactjs

我似乎在这里找不到与这种情况相关的答案。

我在React组件中有状态:

this.state = {
    clubs: [
       {
           teamId: null,
           teamName: null,
           teamCrest: null,
           gamesPlayed: []
        }
    ]
}

我通过API请求接收了一些数据,并且仅更新了部分状态,例如:

this.setState((currentState) => {
    return {
        clubs: currentState.clubs.concat([{
            teamId: team.id,
            teamName: team.shortName,
            teamCrest: team.crestUrl
        }]),
    }
});

稍后,我要修改属性值之一的状态值-gamesPlayed值。

我该怎么做? 如果我使用与上面相同的方法,它只会向数组中添加额外的对象,因此我似乎无法针对该特定对象属性。 我的目的是维护clubs数组中的对象,但修改gamesPlayed属性。

基本上我想做类似的事情:

clubs: currentState.clubs[ index ].gamesPlayed = 'something';

但这不起作用,我不确定为什么。

3 个答案:

答案 0 :(得分:0)

请注意,您正在使用concat()函数,该函数会在数组中添加新项。

您可以使用 findIndex 在对象数组中查找索引并根据需要替换它:

解决方案:

 this.setState((currentState) => {
    var foundIndex = currentState.clubs.findIndex(x => x.id == team.id);
    currentState.clubs[foundIndex] = team;

    return clubs: currentState.clubs
});

答案 1 :(得分:0)

我会更改您的州结构。由于teamId在数组中是唯一的,因此我将其更改为对象。

clubs = {
  teamId: {
    teamName,
    teamCrest,
    gamesPlayed
  }
}

然后您可以像这样更新状态:

addClub(team) {
    this.setState(prevState => ({
      clubs: {
        [team.id]: {
          teamName: team.shortName,
          teamCrest: teamCrestUrl
        },
        ...prevState.clubs
      }
    }));
  }

  updateClub(teamId, gamesPlayed) {
    this.setState(prevState => ({
      clubs: {
        [teamId]: {
          ...prevState.clubs[teamId],
          gamesPlayed: gamesPlayed
        },
        ...prevState.clubs
      }
    }));
  }

这避免了团队必须find遍历整个阵列。您可以从对象中选择它。

您可以根据需要将其转换回数组,如下所示:

Object.keys(clubs).map(key => ({
  teamId: key,
  ...teams[key]
  }))

答案 2 :(得分:-1)

我处理此问题的方法是JSON.parse && JSON.stringify来制作要更改的状态的深层副本,使用该副本进行更改并从那里更新状态。

使用JSON的唯一缺点是,请不要记住复制函数和引用。

以您的示例为例,修改gamesPlayed属性:

let newClubs = JSON.parse(JSON.stringify(this.state.clubs))

newClubs.find(x => x.id === team.id).gamesPlayed.concat([gamesPlayedData])

this.setState({clubs: newClubs})

我假设您每次想从您的API中附加新的gamesPlayedData,并向其中提供team.id和该数据。