我正在用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,
});
};
答案 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以获得更多有关此信息。