参考React官网文档、https://www.jianshu.com/p/8dc...

JSX

JSX是一个 JavaScript 的语法扩大,在HTML模板中嵌入JavaScript语法。因为React认为组件渲染逻辑与UI视图存在外在耦合,而JSX 能够很好地形容UI应该呈现出它应有交互的实质模式,所以React倡议应用JSX语法。JSX齐全能够实现JavaScript原有的性能。

JSX实质是React.createElement的语法糖,如下图例子所示,JSX会被Babel编译为createElement函数调用

createElement()

ReactElement中createElement()是这样定义的`

function createElement(type,config,children)

调用createElement办法返回一个蕴含类型、属性、子节点的对象,这个对象称为React元素,也就是React vdom的节点

virtual dom是React性能优化的重要点,实质是JS对象,所有节点以键值对模式存在,节点也是JS对象,用嵌套模式示意dom的树形构造。

那么createElement办法具体做了什么事呢?

  • 首先遍历config参数也就是节点的属性,保留在props对象中
  • 把children参数封装成数组,保留在props对象中
  • 依据type参数判断节点默认属性,将默认属性也保留在props对象
  • 最初调用ReactElement办法并传入type、props,返回一个对象

ReactElement办法返回的对象长这样

  • $$typeof属性用于检测节点是否为非法的React元素
  • type属性即节点类型
  • key用作节点的惟一标识
  • ref用于获取实在的dom节点
  • props蕴含了节点的默认属性和用户给它定义的属性以及子节点
  • _owner标识该节点隶属于哪个组件

ReactDom.render

createElement创立的React元素是怎么渲染到页面的呢?ReactDom为用户提供了render办法渲染元素。

ReactDOM.render(element, container[, callback])

在提供的 container 里渲染一个 React 元素,并返回对该组件的援用(或者针对无状态组件返回 null)。

如果 React 元素之前曾经在 container 里渲染过,这将会对其执行更新操作,并仅会在必要时扭转 DOM 以映射最新的 React 元素。

如果提供了可选的回调函数,该回调将在组件被渲染或更新之后被执行。

在理论我的项目中,所有组件作为子节点渲染到id为root的div容器

留神

  • ReactDOM.render() 会管制你传入容器节点里的内容。当首次调用时,容器节点里的所有 DOM 元素都会被替换,后续的调用则会应用 React 的 DOM 差分算法(DOM diffing algorithm)进行高效的更新。
  • ReactDOM.render() 不会批改容器节点(只会批改容器的子节点)。能够在不笼罩现有子节点的状况下,将组件插入已有的 DOM 节点中。
  • ReactDOM.render() 目前会返回对根组件 ReactComponent 实例的援用。 然而,目前应该防止应用返回的援用,因为它是历史遗留下来的内容,而且在将来版本的 React 中,组件渲染在某些状况下可能会是异步的。 如果你真的须要取得对根组件 ReactComponent 实例的援用,那么举荐为根元素增加 callback ref。
  • 应用 ReactDOM.render() 对服务端渲染容器进行 hydrate 操作的形式曾经被废除,并且会在 React 17 被移除。作为代替,请应用 hydrate()

为了防止每次计算dom节点差别时递归遍历dom树的操作,React团队给出了React Fiber算法以及fiber tree数据结构(基于单链表的树结构),而render办法就是实现React Fiber算法以及构建fiber tree的外围API。对于这部分的实现,请参考结尾链接。

总结

总而言之,React渲染的过程实际上是由JSX创立React元素作为虚构dom节点,调用render办法创立一棵dom树

对于vdom改天再写一篇具体的总结