版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/nongweiyilady/article/details/83040479
前言
react中,我们通过this.setState()方法去改变自身组件的state,以及子组件的props,然后触发组件重新渲染。
那么,当我们setState之后,新的state和旧的state值是一样,页面也会进行重新渲染,这是不必要的,也是损耗性能的。
举例
写一个demo
import React, { Component } from 'react';
//子组件
const Son = (props) => {
console.log("--son--render----")
return <div> Son: {props.son}</div>
}
//父组件,传给子组件一个on的prop
class App extends Component {
state = {
name: 'scarlet',
son: 2
}
componentDidMount() {
setInterval(() => {
this.setState({
name: this.state.name,
son: this.state.son
})
}, 1 * 1000)
}
render() {
console.log("--parent--render----")
return (
<div className="App">
<h2>name : {this.state.name}</h2>
<Son son={this.state.son}></Son>
</div>
);
}
}
export default App;
代码中有:
state = {
name: 'scarlet',
son: 2
}
其中,name是父组件自己渲染,son是传给子组件渲染。
以上例子中,我们用一个setInterval每隔1s去setState,可以看到以下打印:
从抓的打印中,可以知道,即使我们设置了state,前后的state中的值是一样的,但是在子组件和父组件中,都会触发render。这些操作都是冗余的,没有必要的。
优化
此时钩子函数:shouldComponentUpdate非常关键。
这个函数是re-render是render()函数调用前被调用的,他的两个参数nextProps和nextState,分别表示下一个props和下一个state的值。我们重写这个钩子,当函数返回false时,阻止接下来的render()调用以及组件重新渲染,反之,返回true时,组件向下走render重新渲染。
所以我们可以在父组件中,重写这个方法:
shouldComponentUpdate(nextProps, nextState) {
if (nextState.name !== this.state.name) {
return true
}
return false
}
让他在前后name值不相等的时候才继续重新渲染。
在子组件中,我们这样写:
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.son !== this.props.son) {
return true
}
return false
}
表示当传入的props,当值出现变化的时候才回去重新渲染。
完整的验证代码如下:
import React, { Component } from 'react';
//子组件
class Son extends Component {
shouldComponentUpdate(nextProps, nextState) {
if (nextProps.son !== this.props.son) {
return true
}
return false
}
render() {
console.log("--son--render----")
return <div> Son: {this.props.son}</div>
}
}
//父组件,传给子组件一个on的prop
class App extends Component {
state = {
name: 'scarlet',
son: 2
}
componentDidMount() {
let i = 1;
setInterval(() => {
if (i % 5 === 0) {
console.log("-------------------------", i)
this.setState({
name: 'candy',
son: 9
})
} else {
this.setState({
name: this.state.name,
son: this.state.son
})
}
i++
}, 1 * 1000)
}
shouldComponentUpdate(nextProps, nextState) {
if (nextState.name !== this.state.name) {
return true
}
return false
}
render() {
console.log("--parent--render----")
return (
<div className="App">
<h2>name : {this.state.name}</h2>
<Son son={this.state.son}></Son>
</div>
);
}
}
export default App;
打印如下:
从打印中可以看出,我们实现了控制,当前后state或者props值不一致的时候,我们才会去进行渲染,从而达到了优化的效果。