Skip to main content

React.Component 源码解析

使用 React 组件可以将 UI 拆分为独立且复用的代码片段,每部分都可独立维护。可以通过子类 React.ComponentReact.PureComponent 来定义 React 组件。React.memo 为高阶组件。

一、什么是 React.Component

React.Component 是使用 ES6 Class 方式定义 React 组件的基类:

class Greeting extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}

二、Component 源码分析

/*
Component 基类
1. 设置 react 的 props、content、refs、updater 等属性
2. class 继承是先将父类实例对象的属性和方法,加到 this 上面(所以必须先调用 super 方法)
然后再用子类的构造函数修改 this
*/
function Component(props, context, updater) {
// 传参
this.props = props // 父子传递数据
this.context = context // 跨级传递数据
this.refs = emptyObject // 子到父传递数据 节点实例挂载进来
this.updater = updater || ReactNoopUpdateQueue // 更新数据
}
Component.prototype.isReactComponent = {} // 给 Component 原型上添加属性
/*
使用 setState 来改变 Component 类内部的变量 enqueueSetState 调用这个方法实现更新机制
partialState:要更新的 state,可以是 object / function
*/
Component.prototype.setState = function (partialState, callback) {
// 给 Component 原型上添加 setState 方法
// 判断 setState 中 的partialState 是否符合条件 如果不符合则抛出错误
if (
!(
typeof partialState === 'object' ||
typeof partialState === 'function' ||
partialState == null
)
) {
{
throw Error(
'setState(...): takes an object of state variables to update or a function which returns an object of state variables.'
)
}
}
// state 的更新机制在 react-dom 中实现
this.updater.enqueueSetState(this, partialState, callback, 'setState')
}
// 在 Component 的深层次改变但没有调用 setState 时,调用此方法强制更新一次
Component.prototype.forceUpdate = function (callback) {
this.updater.enqueueForceUpdate(this, callback, 'forceUpdate')
}

三、Component 总结

  • Component 本质是一个类:

    class Component {
    constructor(props, context, updater) {
    this.props = props
    this.context = context
    this.refs = emptyObject
    this.updater = updater || ReactNoopUpdateQueue
    }
    }
  • setState()Component 原型上的方法,其本质是调用 ReactNoopUpdateQueue.js 中的 enqueueSetState() 方法;

  • React.Component() 只涉及了 props / context / refs / updater / isReactComponent / setState / forceUpdate,其他均没有自己实现。