在地图函数中反应 setState [英] React setState in a map function

查看:58
本文介绍了在地图函数中反应 setState的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法解决下面的问题.

I cannot wrap my head around the issue below.

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

The issue relates to the asynchronous setState dimension. Usually I use the callback, but doesn't seem appropriate here.

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

My goal is to create a state (that I will be able to sort) which is obtained by iterating on different states which are themselves created in a map.

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

The function below calls my different methods, the ones we're interested in are the 2 last ones. getUserPoints and 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 来汇总每个用户的玩家的所有点数.

The getUserPoints allow me to dynamically create the state.userPoints summing all the points from the players for each user.

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

Then I was expecting the sortArrayforUserRank below to use the updated state.userPoints to create my final userArrayPoints state.

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

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

Currently the userArrayPoints gets populated with 4 objects {[user]:0} instead of the final sum of points for each user. The issue there is that sortArrayforUserRank gets called before the previous setState are done

我很想在 getUserPoints 中使用 setState 回调,但由于我在玩家地图函数中,它将为每个玩家调用它,而我想在用户 lvl 中处理它最终的积分总和.

I would have loved to use the setState callback in getUserPoints but since I'm in the player map function it will get called for each player whereas I want to handle it at the user lvl to have the final sum of points.

我尝试使用 componentDidUpdate,并按照那些文章使 sur 使用 functionnal setState,但无法弄清楚.

I tried to use componentDidUpdate, and made sur to use functionnal setState as per those articles but couldn't figure it out.

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

非常感谢您的帮助,

谢谢

推荐答案

你不能用 setState 做你在这里尝试的事情,因为它是异步的,并且会与每个可用的不同状态发生冲突for () 循环中的迭代.

You can't do what you are trying here with setState because it is asynchronous and will conflict with the different states available on each iteration in that for () loop.

你可以做的是先提取状态,根据需要操作它,然后运行setState(至少在下面的这个)

What you can do is extract the state first, manipulate it as needed, then run setState (at least in this one below)

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

而且您似乎在整个代码中都遵循了类似的模式.尝试将我在这里所做的应用于其他使用带有 setState 的循环的区域.

And it seems you followed a similar pattern throughout the code. Try and apply what I've done here to the other areas that are using loops with setState inside them.

这篇关于在地图函数中反应 setState的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆