me's People
me's Issues
React的this.setState的异步问题
问题描述
在某个方法中,在调用 setState 之后,希望能立刻拿到新的state,结果一直是老的值。
先说原因
setState是异步执行的。下面是一段官方描述:
incrementCount() {
// 注意:这样 *不会* 像预期的那样工作。
this.setState({count: this.state.count + 1});
}
handleSomething() {
// 假设 `this.state.count` 从 0 开始。
this.incrementCount();
this.incrementCount();
this.incrementCount();
// 当 React 重新渲染该组件时,`this.state.count` 会变为 1,而不是你期望的 3。
// 这是因为上面的 `incrementCount()` 函数是从 `this.state.count` 中读取数据的,
// 但是 React 不会更新 `this.state.count`,直到该组件被重新渲染。
// 所以最终 `incrementCount()` 每次读取 `this.state.count` 的值都是 0,并将它设为 1。
// 问题的修复参见下面的说明。
}
我应该如何更新那些依赖于当前的 state 的 state 呢?
给 setState 传递一个函数,而不是一个对象,就可以确保每次的调用都是使用最新版的 state(见下面的说明)。
给 setState 传递一个对象与传递一个函数的区别是什么?
传递一个函数可以让你在函数内访问到当前的 state 的值。因为 setState 的调用是分批的,所以你可以链式地进行更新,并确保它们是一个建立在另一个之上的,这样才不会发生冲突:
setState 什么时候是异步的?
目前,在事件处理函数内部的 setState 是异步的。
例如,如果 Parent 和 Child 在同一个 click 事件中都调用了 setState ,这样就可以确保 Child 不会被重新渲染两次。取而代之的是,React 会将该 state “冲洗” 到浏览器事件结束的时候,再统一地进行更新。这种机制可以在大型应用中得到很好的性能提升。
这只是一个实现的细节,所以请不要直接依赖于这种机制。在以后的版本当中,React 会在更多的情况下静默地使用 state 的批更新机制。
为什么 React 不同步地更新 this.state?
如前面章节解释的那样,在开始重新渲染之前,React 会有意地进行“等待”,直到所有在组件的事件处理函数内调用的 setState() 完成之后。这样可以通过避免不必要的重新渲染来提升性能。
但是,你可能还是会想,为什么 React 不能立即更新 this.state,而不对组件进行重新渲染呢。
主要有两个原因:
这样会破坏掉 props 和 state 之间的一致性,造成一些难以 debug 的问题。
这样会让一些我们正在实现的新功能变得无法实现。
解决办法
1.设计一个全局变量。(感觉跟react state的**有冲突,本人不推荐使用)
2.直接使用this.state.count = this.state.count + 1 来修改(不会重新渲染组件)
3.给 setState传递一个函数,而不是一个对象(推荐使用)
this.setState((state) => {
const newCount = state.count + 1
console.log(newCount)
return { count: newCount }
})
4.React控制之外的事件中调用setState是同步更新的。比如原生js绑定的事件,setTimeout/setInterval等
setTimeout(()=>{
this.setState({count: this.state.count + 1});
console.log(this.state.count)
});
5.给setState给第二个参数传递一个回调函数(能拿到新值,但是重复调用最终结果只会+1)
this.setState({ count: this.state.count + 1 }, () => {
console.log(this.state.count)
})
参考:https://zh-hans.reactjs.org/docs/faq-state.html#what-does-setstate-do
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.