确保React状态已针对游戏循环进行了更新

时间:2018-11-19 14:03:37

标签: javascript reactjs

我正在用React写一本Conway的《人生游戏》。组件的状态包含grid,描述了当前时间哪些单元处于活动状态。在每个游戏循环中,都会计算出新的grid,并在下一次迭代时更新状态。

在我看来,由于setState是异步的,所以当用iterate重复调用setInterval函数时,我不能保证使用的是grid的当前版本每次iterate运行。

在React中使用setInterval可以避免由setState引起的任何潜在问题吗?

以下是描述游戏循环的相关功能:

  go = () => {
    const { tickInterval } = this.state;
    this.timerId = setInterval(this.iterate, 570 - tickInterval);
    this.setState({
      running: true,
    });
  };

  iterate = () => {
    const { grid, gridSize, ticks } = this.state;
    const nextGrid = getNextIteration(grid, gridSize);
    this.setState({
      grid: nextGrid,
      ticks: ticks + 1,
    });
  };

3 个答案:

答案 0 :(得分:1)

如果您需要基于当前状态设置状态,则直接依赖this.state是错误的,因为它可能是异步更新的。您需要做的是将function传递给setState而不是对象:

this.setState((state, props) => ({
  // updated state
}));

在您的情况下,它将类似于:

iterate = () => {

  this.setState(state => {
    const { grid, gridSize, ticks } = state;
    const nextGrid = getNextIteration(grid, gridSize);
    return {
      grid: nextGrid,
      ticks: ticks + 1
    }
  });

};

答案 1 :(得分:0)

SetState是异步的

this.setState({
    running: true,
});

要使其同步执行一个方法:

this.setState({
     value: true
}, function() {
    this.functionCall() 
})

答案 2 :(得分:0)

如果您查看react官方文档,则setState api确实会采用以下格式的回调:

setState(updater[, callback])

第一个参数将是修改后的state对象,第二个参数将是setState完成执行后要执行的回调函数。

根据官方文档:

  

setState()并不总是立即更新组件。它可能   批处理或将更新推迟到以后。这使得阅读this.state   在调用setState()之后立即发生潜在的陷阱。相反,使用   componentDidUpdate或setState回调(setState(updater,   回调)),保证在更新后都会触发   已应用。如果您需要根据之前的状态设置状态   状态,请阅读下面的updater参数。

您可以查看官方docs以获得更多有关此信息。