我们知道 react
进行页面渲染或者刷新的时候,会从根节点到子节点全部执行一遍,即使子组件中没有状态的改变,也会执行。这就造成了性能不必要的浪费。之前我们了解了泪组件内部可以使用 shouldComponentUpdate
返回布尔值进行判断,本小节我们了解下基于该生命周期实现的另一个判断渲染机制的内置组件。
Component 示例
代码语言:txt复制// src/index.js
class ClassCounter extends React.Component { // 这里我们先使用 Component 类
render() {
console.log('classcounter render')
return <div>classCounter: {this.props.count} ---- { new Date()}</div>
}
}
class App extends React.Component {
state = {
number: 0
}
amountRef = React.createRef()
handleClick = () => {
this.setState({
number: this.state.number this.amountRef.current.value
})
}
render() {
return <div>
<ClassCounter count={this.state.number} />
<input defaultValue={1} ref={this.amountRef} />
<button onClick={this.handleClick}> </button>
</div>
}
}
由上面的两个操作可知,即使子组件的属性值没有变化,页面已然发生了重新渲染。
PureComponent 示例
代码语言:txt复制// src/index.js
class ClassCounter extends React.PureComponent {
render() {
console.log('classcounter render')
return <div>classCounter: {this.props.count} ---- { new Date()}</div>
}
}
换成 PureComponent
后,我们在执行同样的操作,当 props.count
改变时,页面发生了渲染,当 count
没有变化时,页面没有渲染。
实现
代码语言:txt复制// src/react.js
class PureComponent extends Component {
// 我们知道 PureComponent 基于 shouldComponentUpdate 实现的是否渲染
shouldComponentUpdate(nextProps, nextState) {
return !shallowEqual(this.props, nextProps) || !shallowEqual(this.state, nextState)
}
}
// shallowEqual 是一个对比两个对象是否一样的浅比较方法,只比较第一层
// src/utils.js
export function shallowEqual(obj1, obj2) {
// 地址一样
if (obj1 === obj2) {
return true
}
// 不是对象返回 false
if (typeof obj1 !== 'object' || obj1 === null || typeof obj2 !== 'object' || obj2 === null) return false
let keys1 = Object.keys(obj1)
let keys2 = Object.keys(obj2)
if (keys1.length !== keys2.length) return false
for(let k of keys1) {
if (!obj2.hasOwnProperty(k) || obj1[k] !== obj2[k]) {
return false
}
}
return true
}
切换为自己的库,可以看到效果和原生库一样。本节内容同样不是很多,但对于理解 PureComponent
实现机制足够了,如有错误欢迎指正!