React 源码解读

317 阅读1分钟

一、React组件
一个简单的react组件如下

/*
 * A simple React component
 */
class Hello extends React.Component {
  render() {
    return <div>Hello</div>;
  }
}
console.log(<Hello />)

输出组件<Hello />是一个如下所示的对象

输出<Hello><div>world</div></Hello>
在实际组件应用中我们可以通过props.children获取包裹在组件中的元素
不难看出我们平时写的组件,就是一个js的对象的嵌套树结构
<Hello />是继承了React.Component这个类,那么我们首先来看下React.js的源码,

这里我们可以看到React export出了Component、PureComponent、Fragment等模块。 通过import {Component, PureComponent} from './ReactBaseClasses'; 知道Component类是通过ReactBaseClasses.js引入的

function Component(props, context, updater) {
  this.props = props;
  this.context = context;
  this.refs = emptyObject;
  this.updater = updater || ReactNoopUpdateQueue;
}
Component.prototype.isReactComponent = {};
Component.prototype.setState = function(partialState, callback) {
  // ...
  this.updater.enqueueSetState(this, partialState, callback, 'setState');
};
Component.prototype.forceUpdate = function(callback) {
  this.updater.enqueueForceUpdate(this, callback, 'forceUpdate');
};

Component就是一个拥有props、context、refs、updater属性,setState、forceUpdate方的法构造函数,其中setState接收partialStatecallback两个参数。
二、组件的初始化
通过babel解析Hello组件, 得到render方法实际上是调用了React.createElement方法,我们找到ReactElement这个文件,

createElement方法返回一个ReactElement对象,就是我们之前通过console打印出来的结构。

export function createElement(type, config, children) {
  // ...
  return ReactElement(
    type,
    key,
    ref,
    self,
    source,
    ReactCurrentOwner.current,
    props,
  );
}
const ReactElement = function(type, key, ref, self, source, owner, props) {
  const element = {
    // This tag allows us to uniquely identify this as a React Element
    $$typeof: REACT_ELEMENT_TYPE,
    // Built-in properties that belong on the element
    type: type,
    key: key,
    ref: ref,
    props: props,
    // Record the component responsible for creating this element.
    _owner: owner,
  };
  return element;
};

因此React组件的实质是通过执行React.createElement创建出来的ReactElement类型的js对象