PureComponent 表示一个纯组件, 可以用来优化 React 程序, 减少 render 函数执行的次数, 从而提高组件的性能。
在 React 中, 当 prop 或者 state 发生变化时, 可以通过在 shouldComponentUpdate 生命周期函数中执行 return false 来阻止页面的更新, 从而减少不必要的 render 执行。React.PureComponent 会自动执行 shouldComponentUpdate。
不过, pureComponent 中的 shouldComponentUpdate() 进行的是浅比较, 也就是说如果是引用数据类型的数据, 只会比较不是同一个地址, 而不会比较这个地址里面的数据是否一致。浅比较会忽略属性和或状态突变情况, 其实也就是数据引用指针没有变化, 而数据发生改变的时候 render 是不会执行的。如果需要重新渲染那么就需要重新开辟空间引用数据。PureComponent 一般会用在一些纯展示组件上。
使用 pureComponent 的好处: 当组件更新时, 如果组件的 props 或者 state 都没有改变, render 函数就不会触发。省去虚拟 DOM 的生成和对比过程, 达到提升性能的目的。这是因为 react 自动做了一层浅比较。
import React, {Component} from "react";
class Foo extends Component {
render() {
console.log("foo-render")
const {num} = this.props;
return foo-{num};
}
}
class App extends Component {
state = {num: 0,};
handle = () => {
this.setState({num: 0,});
};
render() {
const {num} = this.state;
return (
);
}
}
点击按钮, 即使 num 值不变, 组件 Foo 仍然更新了, 控制台打印了 foo-render。
import React, {PureComponent, Component} from "react";
class Foo extends PureComponent {
render() {
console.log("foo-render")
const {num} = this.props;
return foo-{num};
}
}
只有 num 值改变时, 才会触发 Foo 组件 render。
react 源码搜索 checkShouldComponentUpdate 方法可以看到下面代码, 去掉 dev 内容。
/**
* 是否更新组件
* @param {*} workInProgress
* @param {*} ctor
* @param {*} oldProps
* @param {*} newProps
* @param {*} oldState
* @param {*} newState
* @param {*} nextContext
* @returns true 更新 false 不更新
**/
function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
const instance = workInProgress.stateNode;
// 组件实例上有shouldComponentUpdate方法, 调用拿方法返回值
if (typeof instance.shouldComponentUpdate === 'function') {
let shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext,);
return shouldUpdate;
}
// 重点在这
// 原型上有isPureReactComponent属性, 则是extends PureComponent
// PureComponent在react源码中声明时, 在原型上添加了 isPureReactComponent 属性
PureComponent.prototype.isPureReactComponent === true
if (ctor.prototype && ctor.prototype.isPureReactComponent) {
return (
// 只对props和state浅比较
!shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState));
}
return true;
}
下面代码是 isPureReactComponent 来源, 是 react 在声明 PureComponent 时, 在原型上添加了 isPureReactComponent = true 的属性。
function ComponentDummy() {
}
ComponentDummy.prototype = Component.prototype;
function PureComponent(props, context, updater) {
this.props = props;
this.context = context;
// If a component has string refs, we will assign a different object later.
this.refs = emptyObject;
this.updater = updater || ReactNoopUpdateQueue;
}
const pureComponentPrototype = (PureComponent.prototype = new ComponentDummy());
pureComponentPrototype.constructor = PureComponent;
// Avoid an extra prototype jump for these methods.
Object.assign(pureComponentPrototype, Component.prototype);
// PureComponent 原型上有个 isPureReactComponent 属性, 用来标识是 PureComponent 组件
pureComponentPrototype.isPureReactComponent = true;
所以 if (ctor.prototype && ctor.prototype.isPureReactComponent) {} 判断是 PureComponent 组件, 才走浅比较逻辑。