javascript - 如何在 React 中立即更新 setState
问题描述
我完成了React 井字游戏教程。然后我想添加一些简单的人工智能,这样当玩家移动时,人工智能就会回答。
然而,当我点击一个方块放置一个 X 时,我的动作似乎被丢弃了,而计算机却开始了它的动作。所以状态不会在我移动后立即更新,当 AI 移动时,它还没有“看到”我的移动。我怀疑这可能与 onClick 或 setState 函数在 React 中的工作方式有关,但我无法真正理解它。也许有人可以指出我的代码中的问题?
以下是相关的代码位:
handleClick(i) {
const history = this.state.history;
const current = history[history.length - 1];
if (current.squares[i] || calculateWinner(current.squares)) {
return;
}
const newSquares = current.squares.slice();
newSquares[i] = this.state.xIsNext ? 'X' : 'O';
this.setState({
history: history.concat([{squares: newSquares}]),
xIsNext: !this.state.xIsNext,
step: history.length,
});
this.aiMove('O');
}
aiMove(mark) {
const history = this.state.history;
const current = history[history.length - 1];
const newSquares = current.squares.slice();
const ai = new Ai(mark);
const targetSquare = ai.findBestMove(current.squares);
newSquares[targetSquare] = mark;
this.setState({
history: history.concat([{squares: newSquares}]),
xIsNext: !this.state.xIsNext,
step: history.length,
});
}
handleClick 函数与教程中的相同,只是我添加了this.aiMove('O'); 在最后一行,这似乎把事情搞砸了。 这是我的完整代码。
解决方案
这原来是 setState 是异步的并且没有立即更新状态的问题。更多信息:setState 不会立即更新状态
我将 AI 移动作为第一个 setstate(玩家移动)的回调函数,这解决了问题。
this.setState({
history: history.concat([{squares: newSquares}]),
xIsNext: !this.state.xIsNext,
step: history.length,
}, () => setTimeout(() => this.aiMove('O'), 1000));
推荐阅读
- python - 如何使用 python 以仪表的形式绘制数据,而无需像我必须离线那样进行绘图?
- php - 修改传递给 PHP 匿名函数的变量似乎不会反映在变量原始范围中
- javascript - 无法确定任务 ':react-native-onesignal:compileDebugAidl' 的依赖关系
- architecture - 引导程序与工厂之间有什么不同
- c++ - 如何在 C++ 项目的 Cmake 文件中添加 Mac OS 框架
- node.js - 是否有任何格式字符串可以直接从 GraphicsMagick 对象中读取 Caption[2,120] 数据?
- cassandra - 如何在 cassandra 查询语言中使用 DATE 数据类型编写查询?
- snowflake-cloud-data-platform - 雪花复制到不从 blob 存储中清除的语句中
- java - (TensorflowLite/Android) Unable to instantiate activity ComponentInfo
- vue.js - 如何使用 vue 和 vue2-leaflet 获取地理位置?