参考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改天再写一篇具体的总结