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

我正在阅读reactjs文档的Forms部分,并试着用这个代码演示onChange用法( JSBIN )。

 var React= require('react'); var ControlledForm= React.createClass({ getInitialState: function() { return { value: "initial value" }; }, handleChange: function(event) { console.log(this.state.value); this.setState({value: event.target.value}); console.log(this.state.value); }, render: function() { return ( <input type="text" value={this.state.value} onChange={this.handleChange}/> ); } }); React.render( <ControlledForm/>, document.getElementById('mount') ); 

当我更新浏览器中的<input/>值时, handleChangecallback中的第二个console.log输出与第一个console.log相同的value ,为什么我看不到this.setState({value: event.target.value})的结果this.setState({value: event.target.value})handleChangecallback的范围内?

从React的文档 :

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

如果要在发生状态更改后执行某个function,请将其作为callback传入。

 this.setState({value: event.target.value}, function () { console.log(this.state.value); }); 

正如在React文档中所提到的, setState不能保证被同步触发,所以你的console.log可能会在更新之前返回状态。

Michael Parker提到在setState中传递callback。 状态改变后处理逻辑的另一种方法是通过componentDidUpdate生命周期方法,这是React文档中推荐的方法。

通常我们推荐使用componentDidUpdate()来代替这种逻辑。

当可能有连续的setState被触发时,这是特别有用的,并且你想在每次状态改变之后触发相同的function。 您可以将函数放置在componentDidUpdate ,而不必在每个setState添加一个callback函数。

 // example componentDidUpdate(prevProps, prevState) { if (this.state.value > prevState.value) { this.foo(); } } 

这里的React文档说:

切勿直接改变this.state,因为之后调用setState()可能会取代你所做的变异。 把这个状态看作是不可变的。

setState()不会立即改变this.state,但会创build一个挂起的状态转换。 调用此方法后访问this.state可能会返回现有的值。

无法保证setState调用的同步操作,并且调用可能会批处理以提高性能。 setState()将始终触发重新呈现,除非在shouldComponentUpdate()中实现了条件呈现逻辑。

如果正在使用可变对象,并且在shouldComponentUpdate()中不能实现逻辑,只有当新状态与以前的状态不同时调用setState()才能避免不必要的重新呈现。

那么,如此愚蠢的soloution,但也许它可以帮助不熟悉回退的人。 在我的情况下,我通过使用临时variables解决了这个问题。

我有testing用户,我正在计算正确答案的数量保存到testing状态的问题,并在最后一个问题回答后,我想立即显示正确答案的数量从状态。 然而,国家正在恢复旧的价值。 所以我这样做了:

 const numberOfCorrectQuestionsTemp = this.state.numberOfCorrectQuestions; if (questionCorrect) { numberOfCorrectQuestionsTemp++; } this.setState({ numberOfCorrectQuestions: numberOfCorrectQuestionsTemp, }); if (isLastQuestion) { // display the result in percentage - with actual new value alert((100 / (this.state.numberOfQuestions)) * numberOfCorrectQuestionsTemp + '%'); } 

但是在asynchronous操作之后做更好的解决scheme是使用callback。 你可以在这里find它: 何时使用React setStatecallback