浅析 react源码

指导链接:React 原理解析

1. createElement

JSX 代码会被 Babel 编译为 React.createElement:

<div id="testId">
  <div id="testId2">222</div>
  <div id="testId3">333</div>
</div>

// 解析成以下样子
React.createElement(
  "div", // -> type
  {  	 // -> config: 把内建的几个属性(比如 ref 和 key)剔除后丢到 props 对象
    id: "testId"
  }, 	 // -> children:  大于一 会是一个数组,否则的话只是一个对象
  React.createElement(
    "div",
    {
      id: "testId2"
    },
    "222"
  ),
  React.createElement(
    "div",
    {
      id: "testId3"
    },
    "333"
  )
);

源码 ReactElement.js 文件中:

createElement为:

export function createElement(type, config, children) {}

最后返回ReactElement

// 这就是个工厂函数,帮助我们创建 React Element 的
// 内部代码很简单,无非多了一个 $$typeof 帮助我们标识
// 这是一个 React Element
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;
};

通过 $$typeof 来帮助我们识别这是一个 ReactElement

export const REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;

Symbol.for(key): 返回由给定的 key 找到的 symbol,否则就是返回新创建的 symbol。

2 . Component, PureComponent

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');
};

主要的两点分别是 refs 和 updater
setState 和 forceUpdate 都是调用了 updater 中的方法

// 以下做的都是继承功能,让 PureComponent 继承自 Component
function ComponentDummy() {}
ComponentDummy.prototype = Component.prototype;

/**
 * Convenience component with default shallow equality check for sCU.
 */
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);
// 通过这个变量区别下普通的 Component
pureComponentPrototype.isPureReactComponent = true;

PureComponent 继承自 Component,继承方法使用了很典型的寄生组合式。

Refs 的创建方式:

  • ref={el => this.el = el}
  • React.createRef

延伸: Refs and the DOM

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值