由上一篇文章《React(五):React在什么情况下会render》可知,除初始化组件渲染外,组件会在以下两种情况下发生重渲染:
1、当调用setState()函数时,组件会发生重渲染,即使组件的state未发生改变;
2、当父组件发生重渲染时,其全部子组件都会重渲染。
虽然React的重渲染机制是严谨的,但是也是非常耗时的,我们有两种方式来阻止组件不必要的重渲染。
1、shouldComponentUpdate(nextProps,nextState)
shouldComponentUpdate(nextProps,nextState )是重渲染时render函数调用之前被调用的函数,它接收两个参数:nextProps和nextState,分别表示下一个props和下一个state的值,并且,当函数返回false时,阻止接下来的render()函数的调用,阻止组件重渲染,而返回true时,组件照常重渲染,React默认返回true。
对React(五)中第一个例子(setState引起的重渲染)进行修改:
import React from 'react';
class Test extends React.Component{
constructor(props) {
super(props);
this.state = {
strTest:"render测试" //设state中strTest值
}
}
//这里调用了setState但是并没有改变setState中的值
handleClick = () => {
const prestrTest = this.state.strTest;
this.setState({
prestrTest:this.state.strTest
})
}
//在render函数调用前判断:如果前后state中的内容不变,通过return false阻止render调用
shouldComponentUpdate(nextProps,nextState){
if(nextState.strTest == this.state.strTest){
return false
}
}
render(){
//当render函数被调用时,打印当前的strTest
console.log(this.state.strTest)
return(
<h1 onClick = {this.handleClick}>
{this.state.strTest}
</h1>)
}
}
export default Test;
页面加载后,显示字符串“render测试”,此时点击该字符串,控制台将不再有输出,说明成功阻止了组件的重渲染
对React(五)中第二个例子(父组件引起的重渲染)进行修改:
import React from 'react'
class Son extends React.Component{
//子组件调用shouldComponentUpdate,在render前判断props是否发生变化
shouldComponentUpdate(nextProps,nextState){
if(nextProps.number == this.props.number){
return false
}
return true
}
render(){
const {index,number,handleClick} = this.props;
console.log(number);
return(
<h1 onClick ={() => handleClick(index)}>
{number}
</h1>
)
}
}
class Father extends React.Component{
constructor(props) {
super(props);
this.state = {
numberArray:[1,2,3,4]
}
}
//点击后使numberArray中数组下标为index的数字值发生变化,重渲染对应的Son组件
handleClick = (index) => {
let preNumberArray = this.state.numberArray;
preNumberArray[index] += 4;
this.setState({
numberArray:preNumberArray
})
}
render(){
return(
<div>{
this.state.numberArray.map(
(number,key) => {
return(
<Son
key = {key}
index = {key}
number ={number}
handleClick ={this.handleClick}/>
)
}
)
}
</div>
)
}
}
export default Father
从控制台可以看到,只有子组件1的state发生变化后,组件2,3,4的重渲染成功阻止。
2、PureComponet
除上述使用shouldComponentUpdate()方式阻止重渲染外,还可使用React的PureComponent组件,阻止重渲染。
PureComponet原理:只需要把组件的继承类从Component换成PureComponent即可。PureComponent 自动加载了shouldComponentUpdate 函数,当组件更新时,shouldComponentUpdate 对props和state进行了一层浅比较,如果组件的props和state都没有发生改变,render方法就不会触发,省去Virtual DOM的生成和对比过程,达到提升性能的目的。
但是由于PureComponent对props和state只进行了浅比较,所以对与嵌套的对象并不适用。
欢迎关注公众号“洁儿的漫漫求学路”,互相学习,共同进步~