为什么调用setState方法不会立即改变状态?

好吧,我会尽力使这个快速,因为它应该是一个简单的修复…

我读过一堆类似的问题,答案似乎很明显。 没有什么我永远不得不仰视! 但是…我有一个错误,我无法理解如何解决或为什么发生。

如下:

class NightlifeTypes extends Component { constructor(props) { super(props); this.state = { barClubLounge: false, seeTheTown: true, eventsEntertainment: true, familyFriendlyOnly: false } this.handleOnChange = this.handleOnChange.bind(this); } handleOnChange = (event) => { if(event.target.className == "barClubLounge") { this.setState({barClubLounge: event.target.checked}); console.log(event.target.checked) console.log(this.state.barClubLounge) } } render() { return ( <input className="barClubLounge" type='checkbox' onChange={this.handleOnChange} checked={this.state.barClubLounge}/> ) } 

更多的代码围绕这个,但这是我的问题所在。 应该工作吧?

我也试过这个:

 handleOnChange = (event) => { if(event.target.className == "barClubLounge") { this.setState({barClubLounge: !this.state.barClubLounge}); console.log(event.target.checked) console.log(this.state.barClubLounge) } 

所以我有这两个console.log()的,都应该是相同的。 我真的把状态设置为与上面的行中的event.target.checked一样!

但它总是回到它应该的相反。

当我使用!this.state.barClubLounge ; 如果它开始是错误的,我第一次点击它仍然是假的,即使checkbox被选中或不是基于状态!

这是一个疯狂的悖论,我不知道发生了什么,请帮助!

原因是setState是asynchronous的 ,你不能期望在setState后面更新state值,如果你想检查一下使用callback方法的值。 传递一个方法作为setState完成任务后执行的callbacksetState

为什么setState是asynchronous的?

这是因为setState改变了state并导致重新渲染。 这可能是一个昂贵的操作,并使其synchronous可能会使浏览器无响应。 因此, setState调用是asynchronous以及批处理以获得更好的UI体验和性能。

从Doc

setState()不会立即改变this.state,但会创build一个挂起的状态转换。 调用此方法后访问this.state可能会返回现有的值。 无法保证setState调用的同步操作,并且调用可能会批处理以提高性能。

使用setState的callback方法:

要在setState之后检查更新后的state值,请使用如下所示的callback方法:

 setState({ key: value }, () => { console.log('updated state value', this.state.key) }) 

检查这个:

 class NightlifeTypes extends React.Component { constructor(props) { super(props); this.state = { barClubLounge: false, seeTheTown: true, eventsEntertainment: true, familyFriendlyOnly: false } this.handleOnChange = this.handleOnChange.bind(this); } handleOnChange = (event) => { let value = event.target.checked; if(event.target.className == "barClubLounge") { this.setState({ barClubLounge: value}, () => { //here console.log(value); console.log(this.state.barClubLounge); //both will print same value }); } } render() { return ( <input className="barClubLounge" type='checkbox' onChange={this.handleOnChange} checked={this.state.barClubLounge}/> ) } } ReactDOM.render(<NightlifeTypes/>, document.getElementById('app')) 
 <script src="ajax/libs/react/15.1.0/react.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script> <div id='app'/> 

由于性能考虑,这是devise的。 React中的setState是一个保证重新渲染Component的函数,这是一个代价高昂的CPU进程。 因此,其devise人员希望通过将多个渲染操作合并为一个进行优化,因此setState是asynchronous的。