Javascript 为什么调用 react setState 方法不会立即改变状态?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30782948/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why calling react setState method doesn't mutate the state immediately?
提问by tarrsalah
I'm reading Formssection of reactjsdocumentation and just tried this code to demonstrate onChangeusage (JSBIN).
我正在阅读reactjs文档的Forms部分,只是尝试了这段代码来演示用法(JSBIN)。onChange
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')
);
When I update the <input/>value in the browser, the second console.loginside the handleChangecallback prints the same valueas the first console.log, Why I can't see the result of this.setState({value: event.target.value})in the scope of handleChangecallback?
当我更新<input/>在浏览器中值,第二console.log里面handleChange回调打印同value为第一console.log,为什么我看不到结果this.setState({value: event.target.value})的范围handleChange回调?
回答by Michael Parker
From React's documentation:
来自 React 的文档:
setState()does not immediately mutatethis.statebut creates a pending state transition. Accessingthis.stateafter calling this method can potentially return the existing value. There is no guarantee of synchronous operation of calls tosetStateand calls may be batched for performance gains.
setState()不会立即变异,this.state而是创建一个挂起的状态转换。this.state调用此方法后访问可能会返回现有值。无法保证调用的同步操作,setState并且可能会批处理调用以提高性能。
If you want a function to be executed after the state change occurs, pass it in as a callback.
如果您希望在发生状态更改后执行某个函数,请将其作为回调传入。
this.setState({value: event.target.value}, function () {
console.log(this.state.value);
});
回答by Yo Wakita
As mentioned in the React documentation, there is no guarantee of setStatebeing fired synchronously, so your console.logmay return the state prior to it updating.
正如 React 文档中提到的,无法保证setState同步触发,因此您console.log可能会在更新之前返回状态。
Michael Parker mentions passing a callback within the setState. Another way to handle the logic after state change is via the componentDidUpdatelifecycle method, which is the method recommended in React docs.
Michael Parker 提到在setState. 另一种处理状态更改后逻辑的componentDidUpdate方法是通过生命周期方法,这是 React 文档中推荐的方法。
Generally we recommend using componentDidUpdate() for such logic instead.
通常我们建议使用 componentDidUpdate() 来代替这种逻辑。
This is particularly useful when there may be successive setStates fired, and you would like to fire the same function after every state change. Rather than adding a callback to each setState, you could place the function inside of the componentDidUpdate, with specific logic inside if necessary.
这在可能会连续setState触发 s时特别有用,并且您希望在每次状态更改后触发相同的函数。setState您可以将函数放在 内部,而不是向 each 添加回调,componentDidUpdate如有必要,可以在内部使用特定的逻辑。
// example
componentDidUpdate(prevProps, prevState) {
if (this.state.value > prevState.value) {
this.foo();
}
}
回答by kurokiiru
You could try using ES7 async/await. For instance using your example:
您可以尝试使用 ES7 异步/等待。例如使用您的示例:
handleChange: async function(event) {
console.log(this.state.value);
await this.setState({value: event.target.value});
console.log(this.state.value);
}
回答by yangsibai
Watch out the react lifecycle methods!
注意 react 生命周期方法!
- http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
- https://reactjs.org/docs/react-component.html
- http://projects.wojtekmaj.pl/react-lifecycle-methods-diagram/
- https://reactjs.org/docs/react-component.html
I worked for several hours to find out that getDerivedStateFromPropswill be called after every setState().
我工作了几个小时才发现getDerivedStateFromProps每个setState().
回答by Ritwik
async-awaitsyntax works perfectly for something like the following...
async-await语法非常适用于以下内容...
changeStateFunction = () => {
// Some Worker..
this.setState((prevState) => ({
year: funcHandleYear(),
month: funcHandleMonth()
}));
goNextMonth = async () => {
await this.changeStateFunction();
const history = createBrowserHistory();
history.push(`/calendar?year=${this.state.year}&month=${this.state.month}`);
}
goPrevMonth = async () => {
await this.changeStateFunction();
const history = createBrowserHistory();
history.push(`/calendar?year=${this.state.year}&month=${this.state.month}`);
}
回答by Vishal Bisht
Simply putting - this.setState({data: value}) is asynchronous in nature that means it moves out of the Call Stack and only comes back to the Call Stack unless it is resolved.
简单地说 - this.setState({data: value}) 本质上是异步的,这意味着它移出调用堆栈,除非解决,否则只会返回调用堆栈。
Please read about Event Loop to have a clear picture about Asynchronous nature in JS and why it takes time to update -
请阅读事件循环以清楚了解 JS 中的异步性质以及更新需要时间的原因 -
https://medium.com/front-end-weekly/javascript-event-loop-explained-4cd26af121d4
https://medium.com/front-end-weekly/javascript-event-loop-explained-4cd26af121d4
Hence -
因此 -
this.setState({data:value});
console.log(this.state.data); // will give undefined or unupdated value
as it takes time to update. To achieve the above process -
因为更新需要时间。实现上述过程——
this.setState({data:value},function () {
console.log(this.state.data);
});

