Component与PureComponent源码

1、源码目录:

packages\react\src\ReactBaseClasses.js

2、Component源码

import ReactNoopUpdateQueue from './ReactNoopUpdateQueue';

const emptyObject = {};

/**
 * Component构造函数,用于创建一个类组件的实例
 * @param props 表示所拥有的属性信息
 * @param context 表示所拥有的属性信息
 * @param updater 表示一个updater对象,定义在react-dom,用于处理后续的更新调度任务
 */
function Component(props, context, updater) {
  this.props = props;
  this.context = context;
  // 该属性用于存储类组件实例的引用信息
  // 在React中我们可以有多种方式来创建引用
  // 通过字符串的方式,如:<input type="text" ref="inputRef" />
  // 通过回调函数的方式,如:<input type="text" ref={(input) => this.inputRef = input;} />
  // 通过React.createRef()的方式,如:this.inputRef = React.createRef(null); <input type="text" ref={this.inputRef} />
  // 通过useRef()的方式,如:this.inputRef = useRef(null); <input type="text" ref={this.inputRef} />
  this.refs = emptyObject;
  // 当state发生变化的时候,需要updater对象去处理后续的更新调度任务,没传入设置默认更新器
  this.updater = updater || ReactNoopUpdateQueue;
}

// 在原型上新增了一个isReactComponent属性用于标识该实例是一个类组件的实例
// 函数定义组件是没有这个属性的,所以可以通过判断原型上是否拥有这个属性来进行区分
Component.prototype.isReactComponent = {};

/**
 * 用于更新状态
 * @param partialState 表示下次需要更新的状态
 * @param callback 在组件更新之后需要执行的回调
 */
Component.prototype.setState = function(partialState, callback) {
  this.updater.enqueueSetState(this, partialState, callback, 'setState');
};

/**
 * 用于强制重新渲染
 * @param callback 在组件重新渲染之后需要执行的回调
 */
Component.prototype.forceUpdate = function(callback) {
  this.updater.enqueueForceUpdate(this, callback, 'forceUpdate');
};

说明:isReactComponent属性来区分函数定义组件和类组件

// 返回true则表示类组件,否则表示函数定义组件
function shouldConstruct(Component) {
  return !!(Component.prototype && Component.prototype.isReactComponent);
}

3、PureComponent源码

// 通过借用构造函数,实现典型的寄生组合式继承,避免原型污染
function ComponentDummy() {}
ComponentDummy.prototype = Component.prototype;

// 定义PureComponent构造函数
function PureComponent(props, context, updater) {
  this.props = props;
  this.context = context;
  this.refs = emptyObject;
  this.updater = updater || ReactNoopUpdateQueue;
}

// 将PureComponent的原型指向借用构造函数的实例
const pureComponentPrototype = (PureComponent.prototype = new ComponentDummy());
// 重新设置构造函数的指向
pureComponentPrototype.constructor = PureComponent;
// 合并原型,减少原型链查找所浪费的时间(原型链越长所耗费的时间越久)
Object.assign(pureComponentPrototype, Component.prototype);
// 定义PureComponent标志,用于区分
pureComponentPrototype.isPureReactComponent = true;

export {Component, PureComponent};

4、使用代码

// 源码目录
packages\react-dom\src\server\ReactPartialRenderer.js

// 实例化Component组件
let inst;
if (isClass) {
    inst = new Component(element.props, publicContext, updater);
}