在页面刷新之前反应内容数据不正确

时间:2018-04-15 02:02:22

标签: javascript reactjs firebase firebase-realtime-database

我有一个显示运动员姓名的应用程序,并允许用户根据他们预测的即将到来的表现来上下投票。

我已经开始实施代码来检查玩家阵列并根据他们的投票数量对数据库中的所有玩家进行排名,奖励那些具有相同级别关系的玩家(如果前两个人拥有100个赞成,他们都将排名第一,等等。)

系统似乎工作正常,但是,有时它会让我在播放器旁边的值最终正确之前刷新页面两次。

但是,我主要想知道这是否是一种可以接受的方式来进行这种排名 - 主要是,这种方式在渲染()返回时是否非常低效?我希望数据库中有100多名玩家。

代码中是否还有其他地方可以更高效地进行排名?

这里是代码和一些相关变量:

let prevPlayerVotes = 0
let rankCount = 1

const orderedPlayersRank = _.orderBy(players, ['votes'], ['desc'])
<span className="trendHeaderUp">TRENDING UP</span>
{
    orderedPlayersRank.map((player) => {
        this.database.child(player.id).transaction(function(player) {
            if (player.votes >= prevPlayerVotes) {
                prevPlayerVotes = player.votes
                player.rank = rankCount
            } else if(player.votes < prevPlayerVotes) {
                rankCount++
                player.rank = rankCount
                prevPlayerVotes = player.votes
            } else {
                console.log("Rank calculation error.")
            }
            return player;
        })
    })
}
{
    orderedPlayersUp.map((player) => {
        return (
            <Player
                playerContent={player.playerContent}
                playerId={player.id}
                rank={player.rank}
                key={player.id}
                upvotePlayer={this.upvotePlayer}
                downvotePlayer={this.downvotePlayer}
                userLogIn={this.userLogIn}
                userLogOut={this.userLogOut}
                uid={this.uid}
            />
        )
    })
}
</div>
<div className="playersBody">
    <span className="trendHeaderDown">TRENDING DOWN</span>
    {
        orderedPlayersDown.map((player) => {
            return (
                <Player
                    playerContent={player.playerContent}
                    playerId={player.id}
                    rank={player.rank}
                    key={player.id}
                    upvotePlayer={this.upvotePlayer}
                    downvotePlayer={this.downvotePlayer}
                    userLogIn={this.userLogIn}
                    userLogOut={this.userLogOut}
                    uid={this.uid}
                />
            )
        })
    }
</div>

感谢您的建议。

参考图片:

ref

2 个答案:

答案 0 :(得分:2)

您不想在渲染中进行排名。这样效率很低。

任何时候发生任何变化(例如点击向上/向下投票,或者如果你有一个文本字段和某人键入一个字符),就会触发渲染,并且很可能每个用户操作都不会导致需要重新激活列表。

如果列表只需要排序一次,请在构造函数中执行。

如果每次投票时都需要对列表进行排名,请在构造函数和单击投票按钮时处理的函数中进行排序。

  • 如果单击向上,您只想对trending up进行排名,如果单击向下,则只想对trending down进行排名

答案 1 :(得分:1)

另外要注意的是,使用es6指针功能,如果您没有进行任何其他数据操作,则不需要指定返回

所以而不是

const alwaysTrue = () => { return true };

你可以做到

const alwaysTrue = () => true;

您的代码示例:

  orderedPlayersDown.map((player) => (
        <Player
            playerContent={player.playerContent}
            playerId={player.id}
            rank={player.rank}
            key={player.id}
            upvotePlayer={this.upvotePlayer}
            downvotePlayer={this.downvotePlayer}
            userLogIn={this.userLogIn}
            userLogOut={this.userLogOut}
            uid={this.uid}
        />
    ))