Reactjs 映射函数中的React setState

Reactjs 映射函数中的React setState,reactjs,setstate,Reactjs,Setstate,我不能对下面的问题绞尽脑汁 该问题与异步setState维度有关。通常我使用回调,但在这里似乎不合适 我的目标是创建一个状态(我将能够对其进行排序),该状态是通过迭代在映射中创建的不同状态而获得的 下面的函数调用我的不同方法,我们感兴趣的是最后两个方法getUserPoints和sortArrayforUserRank getPlayersByUser = () => { database .ref(`pools/${this.state.selectedValue}`) .onc

我不能对下面的问题绞尽脑汁

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

我的目标是创建一个状态(我将能够对其进行排序),该状态是通过迭代在映射中创建的不同状态而获得的

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

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]
        }));
      });
  });
});
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] }
    ])
  }));
});
当前,userArrayPoints由4个对象填充
{[user]:0}
,而不是每个用户的最终点数总和。这里的问题是在上一个setState完成之前调用了
sortArrayforUserRank

我很想在
getUserPoints
中使用setState回调,但由于我在player map函数中,它将为每个玩家调用,而我希望在用户lvl处处理它,以获得最终的点数总和

我试图使用
componentdiddupdate
,并根据这些文章要求使用functionnal setState,但无法理解

我们将非常感谢你的帮助


谢谢

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

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


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

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

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


在整个代码中,您似乎遵循了类似的模式。尝试将我在这里所做的应用到其他使用循环的区域,这些循环中包含
setState

找到了一种使用下面所有承诺的方法。它允许我从循环中删除setState并直接处理它,而不必依赖于2个setState。这两个评论/回答都帮助我处理了这个问题

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

  let userCounter = 0;
  let promiseArrays = [];
  this.state[user].map(player => {
    let promise = database
      .ref(`players/${player}`)
      .child("points")
      .once("value")
      .then(data => {
        let points = parseInt(data.val());
        return (userCounter = userCounter + points);
      });
    promiseArrays.push(promise);
  });
  Promise.all(promiseArrays).then(() =>
    this.setState({
      userArrayPoints: this.state.userArrayPoints.concat({
        [user]: userCounter
      })
    })
  );
});

})

找到了一种使用下面所有承诺的方法。它允许我从循环中删除setState并直接处理它,而不必依赖于2个setState。这两个评论/回答都帮助我处理了这个问题

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

  let userCounter = 0;
  let promiseArrays = [];
  this.state[user].map(player => {
    let promise = database
      .ref(`players/${player}`)
      .child("points")
      .once("value")
      .then(data => {
        let points = parseInt(data.val());
        return (userCounter = userCounter + points);
      });
    promiseArrays.push(promise);
  });
  Promise.all(promiseArrays).then(() =>
    this.setState({
      userArrayPoints: this.state.userArrayPoints.concat({
        [user]: userCounter
      })
    })
  );
});

})

只需在this.setState中使用第二个参数

第二个参数是设置状态后将调用的函数

这是我的国家({ 名称:value
},()=>{this.nameofFunctionYouwanttoRunNext()})

只需在this.setState中使用第二个参数

第二个参数是设置状态后将调用的函数

这是我的国家({ 名称:value
},()=>{this.nameofFunctionYouwanttoRunNext()})

让我了解你的
getUserPoints
,有多个用户,每个用户有多个玩家?你能举个例子说明用户对象的样子吗?如果我是正确的,您希望最终
设置组件状态和用户及其总分的状态
,而您不需要进行太多的状态更新。您好@NanduKalidindi我的最终目标是正确的-根据每个用户各自的玩家获得每个用户的总分DB中的单个用户对象看起来像
{userName:“playerName1,playerName2,playerName3…”
我为每个用户设置了一个单独的状态,看起来像
{userName:[playerName1,playerName2,playerName3等]
同时,我的用户状态对象是一个数组
{users:[userName1,userName2等]}
我当前的想法是获得一个最终状态userArrayPoints,它看起来像
{[{userName1:totalUser1Points},{userName2:totalUser2Points}]}
让我了解你的
getUserPoints
,有多个用户,每个用户都有多个玩家?你能给出一个用户对象可能是什么样子的示例吗?如果我是正确的,你想最终
setState
为你的组件状态和用户及其总分,你不需要做那么多状态updates.Hi@NanduKalidindi你在我的最终目标上是对的-根据每个用户各自的玩家得到每个用户的总分DB中的单个用户对象看起来像
{userName:“playerName1,playerName2,playerName3…”
我为每个用户设置一个单独的状态,看起来像
{userName:[playerName1,playerName2,playerName3等]
同时,我的用户状态对象是一个数组
{users:[userName1,userName2等]}
我当前的想法是获得一个最终状态userArrayPoints,看起来像
{[{userName1:totalUser1Points},{userName2 totalUser2Points}}
谢谢@Deryck,但我很难弄清楚它在这种情况下如何帮助我,我肯定没有完全理解你的答案。我假设你的逻辑会在
这个.state.users创建之后在
getUserPoints
中使用。在
getUsersPoints
中,我在
user
中迭代,因为我使用了他们的名字访问数据库中的值。我尝试从循环中删除setState,但总是在解析承诺(来自数据库请求)之前调用setState。这就是