在说createElement之前,首先来比较下下面两种写法。
| 1 | 
 | 
以上两种写法分别是js写法和react写法,很显然,相较于写法一,写法二更符合我们书写html的习惯而且代码也更容易阅读。
那么为什么能用写法二来写呢,我们把代码放进babel里面看一下。
| 1 | 
 | 
可以看到写法二的代码被转成了上述的样子,即,用React.createElement创建了dom节点(虚拟)。我们可以打印看下这个pDom是个什么东西。

从中可以看出pDom实际上就是一个js对象,有如下属性。
- $$typeof唯一标志,它是一个Symbol对象,具有唯一性,在redux中给actions命名的时候用起来很爽。
- keyDOM结构标识,提升diff算法性能。
- props标签属性。
- ref标志真实Dom引用。
- type该虚拟dom的标签类型。
- _owner16版本新加的东西,是个FiberNode对象,直译就是纤维节点,可以理解成片段节点。
- _store暂时不清楚(源码里也没看懂用来干嘛的)
 所以可以这样理解,虚拟节点就是react对dom的一个解析并将其用js对象表示出来。
现在来看下createElement的源码。
首先来看下入参。
| 1 | const RESERVED_PROPS = { //需要过滤的propNames | 
结合之前看的babel编译后的代码我们可以看出来type,config,children代表什么,type是指节点,config是指传给该标签的属性,children是子节点。
接下来看内部代码。
| 1 | let propName; | 
再接下来就是children的处理。
| 1 | 
 | 
在接下来
| 1 | // Resolve default props | 
| 1 | function defineKeyPropWarningGetter(props, displayName) { | 
最后就是返回一个ReactElement对象
| 1 | return ReactElement( | 
以上
