react的核心api-setState想必大家是再熟悉不过了,本文我讲仔细来讲解它的三大特性,你可能有意向不到的收获哦
- 不可变值
- 有时同步有时异步
- 可能会被合并
有些同学看到这三个概念可能会有点疑惑,不要担心,接下来我会为大家一一讲解。
1. 不可变值
不可变值得意思是在state的中声明的值, 不可在setState之前改变(react官方推荐),
例如
class demo01 extends React.Component{
constructor(props){
super(props)
this.state = {
count: 0
}
}
add = ()=> {
// 正确做法
this.setState({
count: this.state.count +1
})
// 错误做法
this.state.count ++
this.setState({
count: this.state.count;
})
}
render() {
<div>
{this.state.count}
<button onClick={this.add} type="button">加1</button>
</div>
}
}
上述例子中的错误写法虽然不会报错,但是react推荐我们使用第一种方法, 想知道为什么请往下面看。
在我们项目开发的过程中,总避不开的话题就是项目优化, 客户: 喂, 你们的这里怎么这么这么慢啊, 什么垃圾玩意啊。面对客户的吐槽我们又不得不回过头来优化我们的代码,在react项目中推荐了几个性能优化的东西,pureComponent,memo, 还有一个shouldComponentUpdate 的生命周期,下面我们着重讲一下这个周期。
总所周知,当shouldComponentUpdate默认返回true,父组件有更新,子组件无条件也更新,有时候子组件并没有发生数据改变并不需要更新为了避免这种情况,我们经常在项目中看到这样的代码
shouldComponentUpdate (nextProps, nextState) {
if (!_isEqual(nextProps.list, this,props.list) ) {
return true; // list不相同可以渲染
}
return false;
}
回到我们不可变值得第一个例子,如果使用了错误的写法,setState之前改变的state的值,导致shouldComponentUpdate比较的时候相等了,就是这样一代性能优化的代码,导致了组件的不渲染,出现了重大bug。所以性能优化一定要结合state不可变值得特性来做。 但是,在我们项目开发中不可避免的我们的同事没有按照规范来,采用了第二种写法,所以我们要考虑清楚什么时候性能优化,有性能问题的时候在来优化。另外推荐一个库immutable.js, 他具有不可变质的特性,优化的时候结合使用,妙哉妙哉。
2. 有时同步有时异步
setState在组件内的普通调用一般都是异步,在自定义事件,setTimeout中是同步,
class demo01 extends React.Component {
componentDidMount () {
// 下面代码是同步
document.body.addEventLisener('click', ()=> {
this.setState({
count : this.state.count + 1
})
console.log(this.setState.count)
})
setTimeout(()=> {
this.setState({
count : this.state.count + 1
})
console.log(this.setState.count)
}, 0)
}
}
2. 可能会被合并
class demo03 extends React.Component {
click() {
// 如下代码会被合并成一次,只会被执行一次 count只会+1
this.setState({
count: this.state.count +1
})
this.setState({
count: this.state.count +1
})
this.setState({
count: this.state.count +1
})
// == END
// 传入函数 不会被合并,下列代码执行三次
this.setState((prevState, props)=> {
return {
count: prevState +1
}
})
this.setState((prevState, props)=> {
return {
count: prevState +1
}
})
this.setState((prevState, props)=> {
return {
count: prevState +1
}
})
}
}
以上就是本次详细讲解。敬请期待下次再见~