Component
vs PureComponent
/memo
的理解以及性能优化
因为现在很多组件常继承
PureComponent
,虽然两者都可以用来继承一个组件类但是,他们之间是有区别的,PureComponent
是对Component
的性能优化,下面就来详细写下为什么
Component
比较两者之前我们要先了解两者的渲染时机,Component
在 state
改变,props
改变,调用this.setState({...})
的时候都会进行渲染
class demo extent Component {
state = {
name: ''
}
componentDidMount() {
this.setState({name: ''})
}
render() {
console.log('render')
return <div>haha</div>
}
}
上面的组件会在this.setState
调用后就会重新传染一次,但是我们可以看出name
状态并没有没被我们用到,也没有改变,这种渲染就是无效渲染,所以为了优化我们通常会使用钩子函数shouldComponentUpdate
来做一些逻辑判断,来确定是否要重新render
一次
class demo extent Component {
state = {
name: ''
}
componentDidMount() {
this.setState({name: ''})
}
shouldComponentUpdate(nextProps,nextState) {
if(this.state.name === nextState.name) {
return false
}else {
return true
}
}
render() {
console.log('render')
return <div>haha</div>
}
}
这样就可以避免无效渲染,优化性能,但是如果这种判断逻辑多到一定程度,光判断逻辑就很复杂,而且每次都要判断也会影响性能,所以才有了 PureComponent
PureComponent
PureComponent
的区别在于相当于自己写了一个shouldComponentUpdate
钩子函数处理, 对props
和state
进行浅比较,所谓浅比较就是之比较内部第一层的各个属性的值是否相同,像对象和数组这种数据类型,如果只改变内部的元素,就不会造成渲染.浅比较所用的函数就是shallowEqual
以下是PureComponent
的判断逻辑
if (this._compositeType === CompositeTypes.PureClass) {
shouldUpdate = !shallowEqual(prevProps, nextProps) || ! shallowEqual(inst.state, nextState);
}
因为PureComponent
中已经实现了shouldComponentUpdate
的功能,所以在内部不推荐使用改钩子函数,使用会报错.
因为对象和数组的内部元素如果引用不改变,只改变内部元素,组件不会渲染.所以在代码中我们应该保证我们在设置props
和state
的时候也应该确保每次设置属性都是新的对象和新的数组,也就是保证属性是不可变对象Immutable
.
class demo extent Component {
state = {
person: {
name: 'haha'
}
}
componentDidMount() {
// this.setState({person: this.state.person}) Error:person引用地址没变,不重新渲染
this.setState({person: {...this.state.person,gender: female}) //引用改变重新渲染
}
render() {
console.log('render')
return <div>{this.state.person.name}</div>
}
}
重要提示
如果父组件阻止渲染,父组件的新的Props
不会传给子组件,但是如果子组件内部的state
发生变化还是会触发重新渲染的
Component vs PureComponent 总结
PureComponent
相较于Component
区别就是,对props
和state
默认进行判断来确定是否渲染,从而减少无效渲染次数. 大部分情况下直接用PureComponent
比较好可以提高性能,但是如果遇到需要频繁修改值重新渲染的组件,用Component
比较好,因为PureComponent
频繁的判断也会影响性能.
React.memo
**memo
和PureComponent
的作用是一样的, 不同的是memo
是生成函数组件浅比较的是Props
,PureComponent
用来生成class组件,比较Props
和state
**