Skip to content

react解析 React.createElement(一) #7

Open
@HerryLo

Description

@HerryLo
Member

react解析 React.createElement(一)

感谢 yck: 剖剖析 React 源码解析,本篇文章是在读完他的文章的基础上,将他的文章进行拆解和加工,加入我自己的一下理解和例子,便于大家理解。觉得yck写的真的很棒 。React 版本为 16.8.6,关于源码的阅读,可以移步到yck react源码解析

本文永久有效链接:react解析: React.createElement(一)

在我们使用React开发项目的过程中,react的引入是必不可少的,因为babel会将JSX语法编译为React.createElement,如下

现在可以定位到ReactElement.js ,查看代码, 文件阅读 createElement 函数的实现

createElement接受三个参数:

export function createElement(type, config, children) {
  // ...省略
  return ReactElement(
    type,
    key,
    ref,
    self,
    source,
    ReactCurrentOwner.current,
    props,
  );
}

type指代这个ReactElement的类型,config 是指元素的属性,children是指子元素,return 调用 ReactElement函数。

// 省略部分
// function createElement中,对于 config 的处理
if (config != null) {
    if (hasValidRef(config)) {
      ref = config.ref;
    }
    if (hasValidKey(config)) {
      key = '' + config.key;
    }
    self = config.__self === undefined ? null : config.__self;
    source = config.__source === undefined ? null : config.__source;
    for (propName in config) {
      if (
        hasOwnProperty.call(config, propName) &&
        !RESERVED_PROPS.hasOwnProperty(propName)
      ) {
        props[propName] = config[propName];
      }
    }
  }

这段代码对 ref 以及 key 做了处理,然后遍历 config 并把内建的几个属性(比如 ref 和 key)放入 props 对象中。

// 省略部分
// function createElement中,对于 children 的处理
const childrenLength = arguments.length - 2;
  if (childrenLength === 1) {
    props.children = children;
  } else if (childrenLength > 1) {
    const childArray = Array(childrenLength);
    for (let i = 0; i < childrenLength; i++) {
      childArray[i] = arguments[i + 2];
    }
    props.children = childArray;
  }

因为会嵌套多个子元素, 所以childrenLength是大于等于一的。把第二个参数之后的参数取出来,这时候 props.children 会是一个数组,否则是一个对象。因此我们需要注意在对 props.children 进行遍历的时候要注意它是否是数组。最后我们来看看ReactElement函数

// function createElement中,返回 一个 ReactElement 对象
// 调用的 ReactElement 函数
const ReactElement = function(type, key, ref, self, source, owner, props) {
  const element = {
    $$typeof: REACT_ELEMENT_TYPE,
    type: type,
    key: key,
    ref: ref,
    props: props,
    _owner: owner,
  };
  // ...省略
  return element
}

其中$$typeof是用来帮助我们识别这是一个 ReactElement, 下面我们来看看,经过createElement转换之后的ReactElement。

下面是打印出来App组件

更多内容:

react解析: React.Children(二)

参考:

yck: 剖剖析 React 源码

Jokcy 的 《React 源码解析》: react.jokcy.me/

ps: 顺便推一下自己的个人公众号:Yopai,有兴趣的可以关注,每周不定期更新,分享可以增加世界的快乐

Activity

self-assigned this
on Aug 3, 2019
zjhjszwx

zjhjszwx commented on Oct 22, 2019

@zjhjszwx

楼主是只读不调试的吗?能否讲一下具体的调试过程

HerryLo

HerryLo commented on Oct 28, 2019

@HerryLo
MemberAuthor

楼主是只读不调试的吗?能否讲一下具体的调试过程

调试过的,是图片没显示出来😂😂

HerryLo

HerryLo commented on Oct 29, 2019

@HerryLo
MemberAuthor

楼主是只读不调试的吗?能否讲一下具体的调试过程

一步步打断点?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @zjhjszwx@HerryLo

      Issue actions

        react解析 React.createElement(一) · Issue #7 · AttemptWeb/Record