关于setState 异步 的一些问题
Posted 木子飞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于setState 异步 的一些问题相关的知识,希望对你有一定的参考价值。
关于setState ,我们首先要有个正确的认识,官网中给出的解释是setState不是保证同步的
这说明它有时候是同步的有时候的异步的,那什么时候是同步,什么时候是异步?
答案是在React库控制之内时,它就会以异步的方式来执行,否则以同步的方式执行。
但大部份的使用情况下,我们都是使用了React库中的组件,例如View、Text、Image等等,
它们都是React库中人造的组件与事件,是处于React库的控制之下,在这个情况下,
setState就会以异步的方式执行。
比如这里有个例子
constructor(props) { super(props); this.state = { name:"lisi" }; } pushnext(){ this.setState({ name:"zhangsan" });
alert(this.state.name)
}
ListHeaderComponent() {
return (
<TouchableOpacity onPress={()=>this.pushnext()}>
<Text style={{width: deviceWidth,backgroundColor: ‘yellow‘ }}>这是头部</Text>
</TouchableOpacity>
)
}
我这里pushnext()方法里面alet 的东西就是"lisi",因为这里setState 在这里是异步执行,那么
要想alert出来"zhangsan"应该怎么做呢?
有两种方式
一、使用setState
的第二传参,传入一个回调(callback)函式,改为像下面这样的代码
pushnext(){ this.setState({ name:"zhangsan" } ,function(){ alert(this.state.name) }); }
二、使用InteractionManager.runAfterInteractions
pushnext(){ this.setState({ name:"zhangsan" });
InteractionManager.runAfterInteractions(() => { alert(this.state.name); });
}
关于setState异步执行还有一个衍生的问题值得探讨就是它独特存在的
setState
可能会引发不必要的渲染(renders)
state
本身的设计是无法直接更改,setState
的设计是用来更动state
值,
也会触发重新渲染(re-render),按照逻辑就是反正不管如何,只要开发者呼叫setState
,
React就去作整个视图的重新渲染就是。所以setState
必定会作重新渲染的执行,只是要如何渲染是由React来决定。
重新渲染(re-render)指的主要是页面上视图(View)的重新再呈现,这是React原本的核心设计,
但这个设计是有一些问题的。最主要的是state(状态)并不一定单纯只用来记录与视图(View)有关的状态,
也有可能是某个内部控制用的属性值,或是只套用在内部使用的资料。当你改变了这些与视图无关的state(状态)值,
以现在的React设计来说,照样要触发重新渲染的执行过程,这在某些复杂的应用时,由于造成不必要的渲染,
也有可能造成效能上的问题。
React提供了shouldComponentUpdate
方法让开发者可以自行判断,自行提供对应的解决方式,
算得上是一种补墙的方法
那么shouldComponentUpdate怎么使用呢?
我们假如一个场景,在一个界面,你在push到下一个界面的时候有个setState方法,如:
pushnext(){ this.setState({ name:"zhangsan" } ,function(){ this.props.navigation.navigate(‘Chat‘,{name:this.state.name}); }); }
你要把这个name传给下一个界面,但是你传的时候有setState,这就会导致该界面又会render一遍,
(有兴趣的小伙伴可以测试一下)这个时候,我们就可以用到shouldComponentUpdate。
我的代码如下
shouldComponentUpdate(nextProps, nextState){ return this.state.others !== nextState.others; }
这句话什么意思呢?这里的 this.state.others 其实是我这个界面需要渲染出来的值,它是我通过网络获取的,
网络获取之前render第一遍,这个时候this.state.others是空,网络获取后this.state.others有值了,
在 shouldComponentUpdate里面一判断发现两者不一样,返回true,然后开始执行render,
把this.state.others render出来了,之后在执行上面的 pushnext()方法,本来要执行render()方法的,
但是一执行shouldComponentUpdate()方法 ,发现这两个值是没有改变,是一样的,所以不再render,
跳转到下一界面。
以上就是我对setState的理解,如有不正确的地方,欢迎大家指正批评
以上是关于关于setState 异步 的一些问题的主要内容,如果未能解决你的问题,请参考以下文章