一次打包错误 引起的对 React Components, Elements, Instance三者的认识
在一次项目重构中,我将filter组件需要的Input
、Select
之类通过Connect
包裹后,通过<MyFromItem />
这种形式当作参数传入。
大致的数据结构如下,component可以传入自定义组件或者直接传入<Input />
这种形式;
1 | [ |
在本地跑的时候,并没有发现问题;然后打包之后就发现跑不通,报错n is not a function
之类的错误;
打开sourcemap之后定位到这个n是rc-form中的getFieldDecorator函数,遂寻找这个值未传入的原因。
调试了多次(打包实在是太慢了……),终于发现是判断类型的时候发生了问题:
1 | // 这里传入了<StaffFormItem /> |
打包之后,这里的type会从Connect
变为n
, j
这种混淆后的形式,万万没想到。
解决问题之后去搜索了一下,出来了3个概念:
Components
Component Instances
Elements
在其他UI框架中的,一般只有模板(Class
)和实例(new Class()
)这样的概念;而在React中,Component Instances
和Elements
不是同一种类型的东西,它们之间没有一对一的关系;
看下面一段代码:
1 | import React, { Component } from 'react'; |
上述这段代码,可以得出:
MyComponent
(这个class自身)是一个Componentelement
是一个对象,但是它不是MyComponent的一个实例。它仅仅描述了一个对象实例(Component Instance
)被创建了,它是一个拥有key
、props
、ref
、type
这些属性的一个对象。在这里,key
和ref
的值为null
,props
是一个空对象,type
即为MyComponent
字符串。一个
MyComponent
的实例将会在element
被render之后被创建(在上述代码中,实例在构造函数中打印)anthor_element
也是一个对象,它的key
、props
、ref
和上面所述的一样,但是它的type
为div
具体可以看React Components, Elements, and Instances
总结一下,可以看出React官方对这几个概念的定义非常清楚:
An element is a plain object describing a component instance or DOM node and its desired properties.
A ReactElement is a light, stateless, immutable, virtual representation of a DOM Element
Component
可以被用来创建一个Instance
,当Instance
被render之后就创建了一个Element
。
创建实例的过程不需要我们手动进行;
多个Element可以描述同一个实例(比如<Parent />
组件的render()
返回了<Child />
,每次触发render
时都会返回一个新的element
,但是已经存在Child
实例可能被复用);
一个Elmenet也可以用于描述多个实例(比如把一个element
存储到一个变量中const a = <Child />
,然后调用多次<div>{a} {a} {a}</div>
)