【问题标题】:State of React Component, wrong order of objects in array from responseReact 组件的状态,响应中数组中对象的错误顺序
【发布时间】:2019-01-18 22:06:21
【问题描述】:

我正在通过 websocket 向 React 应用程序获取数据。我有一个大对象,其中包含游戏数据。它的属性之一是玩家对象数组,如下所示:

{
  propertyX: "X",
  players: [{player1}, {player2}, {player3}],
  propertyY: "Y"
}

问题是,在我的数据库和来自 websocket(Chrome 中的网络选项卡)的响应中,保留了推送的那些播放器对象的顺序,即使我在将游戏插入到组件状态之前 console.log 也可以。然而,当我访问状态时,我会在这个数组中得到不同的玩家顺序,它是按他们在游戏中得分的地方排序的。

来自这个原始数据:

players: [{ place: 2 }, { place: 3 }, { place: 1 }]

我的状态是这样的:

players: [{ place: 1 }, { place: 2 }, { place: 3 }]

这种行为的原因可能是什么?

@编辑 这行代码用于一个游戏

console.log(game.players[0].place) 
this.setState({ game }, () => {
  console.log("callback", game.players[0].place, this.state.game.players[0].place)
});

输出:

4
callback, 1, 1

添加了包含整个组件代码的 pastebin: https://pastebin.com/hHLQMR6y

【问题讨论】:

    标签: javascript arrays reactjs object websocket


    【解决方案1】:

    由于您记录了两次相同的引用 - game.players[0].place 并且它显示了不同的数据,因此您在某处对其进行了变异。

    请记住 this.setState() 进行了浅合并,因此如果您在 setState 行之后访问 game 对象(例如执行 game.players = ...),您将同时改变局部变量和生成的状态来自它。

    【讨论】:

    • 我确认这是问题所在,我在其中一个子组件中使用了 .sort() 而没有创建副本,因此它改变了从父组件传下来的原始道具。
    【解决方案2】:

    好吧,没有看到您的代码,我没有太多工作要做,但可能是您错误地设置了状态。其他需要考虑的是this.setState({}) 不会立即发生,它实际上是异步的。因此,如果您尝试在设置之前访问状态,您将收到旧数据。您可以提供回调函数作为第二个参数,以便在设置状态后运行:

    const callback = () => {
        console.log(this.state.players);
    }
    
    this.setState({
        players: newPlayers
    }, callback);
    

    【讨论】:

    • 嘿,我编辑了我的问题,我在回调内部进行控制台日志记录,我得到错误的订单数据,所以它与它有关,但我不知道是什么原因为此。
    • 在您的 console.log 中,您正在直接访问游戏对象。您需要使用this.state.game.players[0].place。在使用状态下的对象时,请确保仅使用 this.state 访问它们并使用 this.setState({}) 更新它们。更新时克隆对象并使用克隆更新状态。
    • 不幸的是,如果我这样做 this.state.game.players[0].place 行为是相同的,我会得到错误的顺序。此外,设置状态不应该改变我原来的响应变量,而且看起来确实如此。
    猜你喜欢
    • 2020-11-30
    • 1970-01-01
    • 1970-01-01
    • 2021-09-09
    • 2015-01-22
    • 2020-01-19
    • 1970-01-01
    • 2021-03-31
    • 2021-12-25
    相关资源
    最近更新 更多