理解
现在官网将PureComponent
归类为 过时API
,官网建议最新代码不要使用 PureComponent, 将组件定义为函数而不是类。
在15的版本出现的组件,纯组件PureComponent,定制了shouldComponentUpdate后的Component(浅比较),实现了一个预定义的比较方式,如果数据没有发生更改,就不会再进行组件的渲染。
因为这里是进行了一个浅比较操作,只比较第一层,所以对象内深层次的数据就无法比较。
用法:
import React from 'react'
class Comment extends React.PureComponent {
}
PureComponent是Component的一个子类,支持所有的Component api。扩展PureComponent相当于定义一个自定义的shouldComponentUpdate方法,该方法可以粗略地比较道具和状态。
要使用PureComponent组件的特性应遵循以下几点(需要注意):
- 确保数据类型是值类型
- 如果是引用类型,保证地址不变(还是同一个对象,不是新的对象),同时不应当有深层次的数据变化
缺点:必须使用类的类型(class形式)
代码对比
例子:
使用Component
这里可以看到,在使用 Component 的情况下,即时赋值和原来是一致的,组件每次操作也会渲染。
对比:
使用 PureComponent
import React, { Component, PureComponent } from 'react'
import { Button } from 'antd'
export default class Demo extends PureComponent {
state = {
name: '123'
}
render() {
console.log("render");
return (
<div>
<p>{this.state.name}</p>
<Button type='primary' onClick={() => {
this.setState({
name: '123'
})
console.log("点击了 ---对比");
}}>按钮</Button>
</div>
)
}
}
运行结果:
对比,点击了多次,但是代码渲染只有一次
可以发现:PureComponent类似于Component,但它跳过了对相同道具和状态的重新渲染。
不适用情况
当修改数组内的数组时:
import React, { Component, PureComponent } from 'react'
import { Button } from 'antd'
export default class Demo extends PureComponent {
state = {
arr: [10, 20, 30]
}
render() {
console.log("render");
let { arr } = this.state
return (
<div>
{arr.map((item, index) => <p key={item + index}>{item}</p>)}
<Button type='primary' onClick={() => {
arr.push(40)
console.log(arr, 'arr');
// 直接修改数组内容
this.setState({ arr })
}}>添加</Button>
</div>
)
}
}
运行结果:
依赖的组件对比发现 PureComponent 是不能添加数据的
原因:这里 PureComponent 进行的是浅比较,在这里点击 添加 按钮,然后修改状态值,改动前后的状态值都是 arr ,地址指向的都是state 下的arr数组,改动前后,地址没有发生变化
经过浅比较对比,发现这里的内容是相等的,所以不进行更新
如果想对数组内容进行更新,只能改变数组指向的指针位置变更
改动: this.setState({ arr: [...arr] })
这个等于指向新数组,数据变化
运行结果:
PureComponent和Component的区别
PureComponent会给类组件默认加一个shouldComponentUpdate周期函数
-
在此周期函数中,它对新老的属性/状态 会做一个钱浅比较
-
如果经过浅比较,发现属性和状态并没有改变,则返回false「也就是不继续更新组建」;有变化才会去更新!!