在地图函数中反应 setState

Mat*_*lon 3 setstate reactjs

我无法理解下面的问题。

该问题与异步 setState 维度有关。通常我使用回调,但这里似乎不合适。

我的目标是创建一个状态(我将能够对其进行排序),该状态是通过迭代本身在地图中创建的不同状态来获得的。

下面的函数调用我的不同方法,我们感兴趣的是最后两个方法。getUserPointssortArrayforUserRank

getPlayersByUser = () => {
database
  .ref(`pools/${this.state.selectedValue}`)
  .once("value")
  .then(data => {
    for (let item in data.val()) {
      this.setState({
        users: this.state.users.concat([item])
      });
      this.setState({ [item]: data.val()[item] });
    }
  })
  .then(this.makePlayersArray)
  .then(this.getUserPoints)
  .then(this.sortArrayforUserRank);


  getUserPoints = () => {
this.state.users.map(user => {
  // Create the dynamic name of the state, 1 for each user
  let userPoints = `${user}points`;

  // initializing the state for userPoint to be at 0 for future calculation
  this.setState({ [userPoints]: 0 });

  this.state[user].map(player => {
    database
      .ref(`players/${player}`)
      .child("points")
      .once("value")
      .then(data => {
        let points = parseInt(data.val());
        this.setState(state => ({
          [userPoints]: points + state[userPoints]
        }));
      });
  });
});
Run Code Online (Sandbox Code Playgroud)

getUserPoints允许我动态创建 state.userPoints,总结每个用户的玩家的所有分数。

然后我期望sortArrayforUserRank下面使用更新后的 state.userPoints 来创建我的最终 userArrayPoints 状态。

sortArrayforUserRank = () => {
this.state.users.map(user => {
  let userPoints = `${user}points`;
  this.setState(state => ({
    userArrayPoints: state.userArrayPoints.concat([
      { [user]: state[userPoints] }
    ])
  }));
});
Run Code Online (Sandbox Code Playgroud)

目前,userArrayPoints 填充了 4 个对象,{[user]:0}而不是每个用户的最终点数总和。问题是sortArrayforUserRank在之前的 setState 完成之前被调用

我很想使用 setState 回调,getUserPoints但由于我在玩家地图函数中,每个玩家都会调用它,而我想在用户等级处处理它以获得最终的点数总和。

我尝试使用componentDidUpdate, 并让 sur 按照这些文章使用功能 setState 但无法弄清楚。

https://medium.com/@shopsifter/using-a-function-in-setstate-instead-of-an-object-1f5cfd6e55d1

https://medium.freecodecamp.org/function-setstate-is-the-future-of-react-374f30401b6b

我们将非常感谢您的帮助,

谢谢

Der*_*yck 5

您无法执行此处尝试的操作,setState因为它是异步的,并且会与该循环中每次迭代上可用的不同状态发生冲突for ()

您可以做的是首先提取状态,根据需要对其进行操作,然后运行setState(至少在下面的这个中)

.then(data => {
    // Pull out what you want to mess with here first
    const users = [ ...this.state.users ];
    const dataValObj = data.val();

    // Then use spread operator (or Object.assign/Array.concat)          
    this.setState({
      users: [ 
          ...users, 
          ...Object.keys(dataValObj)
      ],
      ...dataValObj
    });
})
Run Code Online (Sandbox Code Playgroud)

看来您在整个代码中都遵循了类似的模式。setState尝试将我在这里所做的应用到内部使用循环的其他区域。