在说createElement之前,首先来比较下下面两种写法。
1 |
|
以上两种写法分别是js写法和react写法,很显然,相较于写法一,写法二更符合我们书写html的习惯而且代码也更容易阅读。
那么为什么能用写法二来写呢,我们把代码放进babel里面看一下。
1 |
|
可以看到写法二的代码被转成了上述的样子,即,用React.createElement创建了dom节点(虚拟)。我们可以打印看下这个pDom是个什么东西。
从中可以看出pDom实际上就是一个js对象,有如下属性。
$$typeof
唯一标志,它是一个Symbol对象,具有唯一性,在redux中给actions命名的时候用起来很爽。key
DOM结构标识,提升diff算法性能。props
标签属性。ref
标志真实Dom引用。type
该虚拟dom的标签类型。_owner
16版本新加的东西,是个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( |
以上