react核心api之setState详解

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
				}
			})
		}
		
}

以上就是本次详细讲解。敬请期待下次再见~

原创文章 17 获赞 65 访问量 6478

猜你喜欢

转载自blog.csdn.net/m0_37685031/article/details/106074402