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
组件, 才走浅比较逻辑。