react-source-learn
react-source-learn copied to clipboard
React源码系列(二): 从jsx到createElement
我们先思考两个问题
- 浏览器是怎么识别我们写的jsx?
- 为什么甚至在我们的代码并没有使用 React 的情况下,也需要在文件顶部写
import React from 'react'
jsx
首先,什么是jsx?
jsx 一种 JavaScript 的语法扩展,你可以在里面写你的 html + js。
然后babel就会帮我们调用 React.createElement
。 这也是为什么我们就算文件内没用到 React,也需要引入的原因。 以下两种写法的结果是一样的,一个是手动调用,一个是babel帮忙做了这层操作。
createElement(type, [config], [childrens])文件传送
createElement 是将jsx转为 ReactElement的函数, 我们把 Element
标签打印出来可以看到这个对象就是我们所说的ReactElement
。
这里面主要是处理一下 key, ref, defaultProps, 然后将其他的参数和 childrens 放到props对象,最后调用ReactElement。
我们再来看个复杂一点的例子,这个例子我们有多个childrend,而且有多个层级,这时候 babel会根据我们的jsx结构,从子级一层一层调用createElement,并把返回的 reactElement 作为父级的children,所以这里的 childrens 其实可以理解成是一棵 React Element Tree。
上面我们写的都是直接写jsx,如果是一个 Class 形式的ReactComponent,其实也一样,只是type从原来的dom标签变成传入的类。
关于React.Component其实可以理解为只是简单的为一个类,里面包含一些属性,原型链上写了几个公用的方法,后面会针对某些方法(setState)拿出来讲。
到这一步,我们只是做了从jsx语法到React Element的转换,但基本上React
库的部分就到这里了。
你没有看错,react库其实提供的API就那么几个,如 createElement, Component, createContext等。剩下的大部分其实都抽象到 React-dom,react-scheduler等其他库,也是这种抽象使得React拥有跨平台的优势。