我目前正在构建一个TicTacToe游戏,并希望将我当前的玩家存储为currentPlayer状态。一名玩家移动后,我将currentPlayer更新为对方玩家。但是,当我尝试将新状态记录到控制台时,它不会生成更新状态的值。
这是我的代码:
state = {
currentPlayer: 'X',
}
// This function is triggered by an onClick attribute.
// It first finds the html element and renders the currentPlayer value from state.
// It then switchs the value of currentPlayer from X to O and calls setState to update the state.
// Why does the console.log not show the updated state value?
userDidMove = () => {
document.getElementById('cell').innerHTML = this.state.currentPlayer
let nextPlayer = this.state.currentPlayer === 'X' ? 'O' : 'X'
this.setState({
currentPlayer: nextPlayer,
})
console.log ('userDidMove changed state with ',this.state.currentPlayer)
}
任何帮助弄清楚如何让这个函数返回更新的状态值将是伟大的!
状态变化是asynchronous
。当新状态依赖于先前状态时,请改用状态更新程序功能。
提交状态更改后,您可以使用具有更新状态的回调。
this.setState((previousState) => {
const nextPlayer = previousState.currentPlayer === 'X' ? 'O' : 'X';
return {
currentPlayer: nextPlayer
}
}, () => {
// your updated state related code here
console.log('userDidMove changed state with ', this.state.currentPlayer)
});
this.setState(updatedFunc, callback);
setState
是异步的,因此状态不会立即更新。您可以将回调作为setState
的第二个参数传递,只有在状态更新时才会调用:
this.setState(
{ currentPlayer: nextPlayer },
() => console.log(`userDidMove changed state with ${this.state.currentPlayer}`)
);
setState
(React Docs):
setState(updater[, callback])
或setState(stateChange[, callback])
将setState()视为请求而不是更新组件的立即命令。为了获得更好的感知性能,React可能会延迟它,然后在一次通过中更新几个组件。 React不保证立即应用状态更改。
setState()并不总是立即更新组件。它可以批量推迟更新或推迟更新。这使得在调用setState()之后立即读取this.state是一个潜在的陷阱。相反,使用componentDidUpdate或setState回调(setState(更新程序,回调)),其中任何一个都保证在应用更新后触发。如果需要根据以前的状态设置状态,请阅读下面的updater参数。
注意:我建议使用React Dev Tools观察状态,而不是记录它。
更新:这个答案最初说错了,setState
返回了一个承诺,并建议你可以链接.then()
,一旦状态更新就会被调用。我已经纠正了答案,灵感来自@Sushanth的answer。
状态变化是asynchronous
。所以使用函数而不是setState
函数的第二个参数你可以调用console
的回调函数或其他事情来做。
this.setState(() => ({currentPlayer: nextPlayer}), () => {
console.log('state', this.state.currentPlayer);
})