洞悉细节!react 16.8.6源码分析-3 元素创建

本文是作者对React 16.8.6源码的详细分析,重点关注ReactElement的构造过程,包括如何创建React元素,设置属性,元素克隆,以及react元素的验证和遍历上下文的维护。文章通过实例展示了源码中的关键步骤,并提及了相关源码仓库链接,供读者进一步研究。
摘要由CSDN通过智能技术生成

前言

作为一个前端页面仔和需求粉碎机,在日常的工作中重复雷同的业务需求,能够获得的提高是很有限的。要想跳出此山中,开阔新视野,笔者墙裂建议大家阅读市面上顶尖开源库的源码。这是学习和掌握js语言特性的绝佳机会(前端发展到现在,大型应用高度依赖框架,正常情况下普通开发者是没有机会接触底层的语言特性),同时也是深刻理解框架底层思维的契机。这里笔者选择react第一个开刀,市面上不少关于react源码分析的文章要么过于老旧,要么只截取部分代码或者是伪代码,笔者这里将选取react的16.8.6版本作为示例,从第0行开始,不漏过任何一个源码细节,和大家分享笔者在源码阅读过程中的体会。希望和大家共同进步,本系列博文中涉及的源码本人会放在git仓库中,链接在文末。

正文

  1. reactElement的构造函数
//  定义一个创建react 元素的构造函数,这跟class模式的组建不一样,请不要使用new来调用,所有instanceof来检查是失效的,不要使用要用Symbol.for('react.element'),而要用$$typeof来检查,
//  来判断是否是react组件

//  self是一个暂时的变量,是用来判断当React.createElement被调用的时候this和owner是否一致,以便我们告警。我们打算摆脱owner这个概念并且
//  使用箭头函数,只要这个二者一致,组件就没有变化
//  source是一个注释对象(被转译器或者其他文件名,行数,等信息所添加)
/**
 * Factory method to create a new React element. This no longer adheres to
 * the class pattern, so do not use new to call it. Also, no instanceof check
 * will work. Instead test $$typeof field against Symbol.for('react.element') to check
 * if something is a React Element.
 *
 * @param {*} type
 * @param {*} key
 * @param {string|object} ref
 * @param {*} self A *temporary* helper to detect places where `this` is
 * different from the `owner` when React.createElement is called, so that we
 * can warn. We want to get rid of owner and replace string `ref`s with arrow
 * functions, and as long as `this` and owner are the same, there will be no
 * change in behavior.
 * @param {*} source An annotation object (added by a transpiler or otherwise)
 * indicating filename, line number, and/or other information.
 * @param {*} owner
 * @param {*} props
 * @internal
 */

 // react元素构造函数
 // 返回的其实是element对象
var ReactElement = function (type, key, ref, self, source, owner, props) {
   
  var element = {
   
    //  通过这个标签来识别react的元素
    // 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
  };

  {
   
    //  这个验证标志是可变的,我们把这个放在外部支持存储,以便我们能够冻结整个对象,
    //  这个可以被若映射替代,一旦在开发环境下实现了

    // The validation flag is currently mutative. We put it on
    // an external backing store so that we can freeze the whole object.
    // This can be replaced with a WeakMap once they are implemented in
    // commonly used development environments.
    element._store = {
   };

    // 为了更加方便地进行测试,我们设置了一个不可枚举的验证标志位,以便测试框架忽略它
    // To make comparing ReactElements easier for testing purposes, we make
    // the validation flag non-enumerable (where possible, which should
    // include every environment we run tests in), so the test framework
    // ignores it.

    //  给_store设置validated属性false
    Object.defineProperty(element._store, 'validated', {
   
      configurable: false,
      enumerable: false,
      writable: true,
      value: false
    });
    //  self和source都是开发环境才存在的

    // self and source are DEV only properties.
    Object.defineProperty(element, '_self', {
   
      configurable: false,
      enumerable: false,
      writable: false,
      value: self
    });
    //  两个再不同地方创建的元素从测试的角度来看是相等的,我们在列举的时候忽略他们

    // Two elements created in two different places should be considered
    // equal for testing purposes and therefore we hide it from enumeration.
    Object.defineProperty(element, '_source', {
   
      configurable: false,
      enumerable: false,
      writable: false,
      value: source
    });
    //  如果Object有freeze的实现,我们冻结元素和它的属性
    if (Object.freeze) {
   
      Object.freeze(element.props);
      Object.freeze(element);
    }
  }

  return element;
};

这里首先引出ReactElement的构造函数,注意react内部是使用$$typeof来判断react 元素的类型的。使用_store来记录内部的状态,后面会有用到。为了方便测试框架,_store中定义了不可配置不可枚举的validated属性。类似的,框架内部定义了self和source的副本_self_source,他们都是不可配置不可枚举不可写的。

  1. 创建一个给定类型的ReactElement

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值