加载中...
React源码(一)-JSX
发表于:2020-01-01 | 分类: 前端

TODO:

学习React源码的前提就是知道jsx,在react中并不是直接操作真实dom,而是通过jsx的语法,然后经过babel将jsx编译为ReactElement

所以最初的流程就是 jsx -> babel -> ReactElement。

以代码的形式看就如下
jsx

function App({age}) {
	return (
		<div key={1} className="container">
        	hello world
          	<p>I'm {age}</p>
        </div>
	)
}
ReactDOM.createRoot(document.getElementById('root')).render(
    <App age={26} />
);

经过babel转换后的代码

function App({
  age
}) {
  return React.createElement(
    "div",
    {
      key: 1,
      className: "container"
    },
    "hello world",
    React.createElement("p", null, "I'm ", age)
  );
}
ReactDOM.createRoot(document.getElementById('root')).render(
  React.createElement(App, {
    age: 26
  })
);

React 在packages/react/src/ReactElement.js 中实现了createElement方法。

该方法会在运行时执行createElement(type, config, children)返回一个ReactElement,其结构如下:

export const REACT_ELEMENT_TYPE: symbol = Symbol.for('react.element');
// ...
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,
}

其中,比较重要的就是

  • $$typeof : 唯一标识,表示是否为ReactElement,在后续的逻辑中会用到
  • type : 表示的是当前的ReactElement类型,如果当前Element是一个宿主元素div,那么type就是’div’ string类型,如果是一个函数,那么久表示函数本身
  • key : 这个属性就是在diff是优化用的
  • props
    • children : 子节点
    • …其他的 : className、styles、ref …

到这里,对react的jsx、ReactElement就有了一定的了解了。不过,react作为一个前端框架,它和jquery直接操作DOM不同,它是基于状态驱动的。

jsx变化 -> ReactElement更新 -> reconciler、renderer -> 调用宿主API(DOM或其他平台) -> 显示真实DOM
可当前ReactElement这种结构

  1. 并不能表达节点与节点之间的关系,它只知道子节点
  2. 属性太少,无法表达节点的状态,比如一个函数组件需要和当前节点的上下文绑定,它就无法做到。

所以React 实现了一种新的结构FiberNode,这也是React中的虚拟DOM实现。它的特点如下:

  • 介于ReactElement和真实DOM之间: jsx变化 -> ReactElement更新 -> FiberNode -> reconciler、renderer -> 调用宿主API(DOM或其他平台) -> 显示真实DOM

  • 能够表达节点之间的关系

  • 方便拓展(它既是数据存储单元,又是工作单元-> workLoop工作循环)

在下一节会讲解reconciler

上一篇:
React源码(二)-FiberNode
下一篇:
如何通过Hexo + Github Pages部署react项目
本文目录
本文目录