为什么调用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/>
值时, handleChange
callback中的第二个console.log
输出与第一个console.log
相同的value
,为什么我看不到this.setState({value: event.target.value})
的结果this.setState({value: event.target.value})
在handleChange
callback的范围内?
从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