RN渲染原理2
e, shouldHaveDebugID)在分析这个函数之前,我们先来补充一下React组件相关知识。Reac
t组件可以分为两种:元组件:框架内置的,可以直接使用的组件。例如:View、Image等。它在React Na
tive中用ReactNativeBaseComponent来描述。复合组件:用户封装的组件,一般可以通过Re
act.createClass()来构建,提供render()方法来返回渲染目标。它在React Native
中用ReactCompositeComponent来描述。instantiateReactComponent(
node, shouldHaveDebugID)方法根据对象的type生成元组件或者复合组件。复制代码/**
* Given a ReactNode, create an instance that will actua
lly be mounted. * * @param {ReactNode} node * @param {b
oolean} shouldHaveDebugID * @return {object} A new inst
ance of the element's constructor. * @protected */funct
ion instantiateReactComponent(node, shouldHaveDebugID)
{ var instance; if (node === null || node === false)
{ instance = ReactEmptyComponent.create(instantiateR
eactComponent); } else if (typeof node === 'object') {
var element = node; var type = element.type;
if (typeof type !== 'function' && typeof type !== 'stri
ng') { var info = ''; if (process.env.NODE_EN
V !== 'production') { if (type === undefined ||
typeof type === 'object' && type !== null && Object.key
s(type).length === 0) { info += ' You likely f
orgot to export your component from the file ' + 'it\'s
defined in.'; } } info += getDeclarat
ionErrorAddendum(element._owner); !false ? process
.env.NODE_ENV !== 'production' ? invariant(false, 'Elem
ent type is invalid: expected a string (for built-in co
mponents) or a class/function (for composite components
) but got: %s.%s', type == null ? type : typeof type, i
nfo) : _prodInvariant('130', type == null ? type : type
of type, info) : void 0; } //如果对象的type为string,则调用
ReactHostComponent.createInternalComponent(element)来注入生
成组件的逻辑 if (typeof element.type === 'string') {
instance = ReactHostComponent.createInternalComponent(e
lement); } //如果是内部元组件,则创建一个type实例 else if (isI
nternalComponentType(element.type)) { // This is t
emporarily available for custom components that are not
string // representations. I.e. ART. Once those a
re updated to use the string // representation, we
can drop this code path. instance = new element.t
ype(element); // We renamed this. Allow the old na
me for compat. :( if (!instance.getHostNode) {
instance.getHostNode = instance.getNativeNode;
} } //否则,则是用户创建的复合组件,这个时候创建一个ReactCompositeComp
onentWrapper实例,该实例用来描述复合组件 else { instance = ne
w ReactCompositeComponentWrapper(element); } //当对
象为string或者number时,调用ReactHostComponent.createInstanceFo
rText(node)来注入组件生成逻辑。 } else if (typeof node === 'stri
ng' || typeof node === 'number') { instance = ReactH
ostComponent.createInstanceForText(node); } else {
!false ? process.env.NODE_ENV !== 'production' ? invari
ant(false, 'Encountered invalid React node of type %s',
typeof node) : _prodInvariant('131', typeof node) : vo
id 0; } if (process.env.NODE_ENV !== 'production') {
process.env.NODE_ENV !== 'production' ? warning(type
of instance.mountComponent === 'function' && typeof ins
tance.receiveComponent === 'function' && typeof instanc
e.getHostNode === 'function' && typeof instance.unmount
Component === 'function', 'Only React Components can be
mounted.') : void 0; } // These two fields are used
by the DOM and ART diffing algorithms // respectively.
Instead of using expandos on components, we should be
// storing the state needed by the diffing algorithms
elsewhere. instance._mountIndex = 0; instance._mountI
mage = null; if (process.env.NODE_ENV !== 'production'
) { instance._debugID = shouldHaveDebugID ? getNextD
ebugID() : 0; } // Internal instances should fully co
nstructed at this point, so they should // not get any
new fields added to them at this point. if (process.e
nv.NODE_ENV !== 'production') { if (Object.preventEx
tensions) { Object.preventExtensions(instance);
} } return instance;}该方法根据对象的type生成元组件或者复合组件,具体流程如下:
如果对象的type为string,则调用ReactHostComponent.createInternalCo
mponent(element)来注入生成组件的逻辑,如果是内部元组件,则创建一个type实例,否则,则是用户
创建的复合组件,这个时候创建一个ReactCompositeComponentWrapper实例,该实例用来描
述复合组件。当对象为string或者number时,调用ReactHostComponent.createIn
stanceForText(node)来注入组件生成逻辑。以上都不是,则报错。我们通过前面的分析,了解了整个U
I开始渲染的时机,以及js层的整个渲染流程,接下来,我们开始分析每个js的组件时怎么转换成Android的组件
,最终显示在屏幕上的。上面我们提到元组件与复合组件,事实上复合组件也是递归遍历其中的元组件,然后进行渲染。所以
我们重点关注元组件的生成逻辑。我们可以看到,UI渲染主要通过UIManager来完成,UIManager是一个
ReactModule,UIManager.js里的操作都会对应到UIManagerModule里来。我们接着
来看看Java层的渲染流程。3.2 Java层组件渲染从上图我们可以很容易看出,Java层的组件渲染分为以下几
步:JS层通过C++层把创建View的请求发送给Java层的UIManagerModule。UIManager
Module通过UIImplentation对操作请求进行包装。包装后的操作请求被发送到View处理队列UIV
iewOperationQueue队列中等待处理。实际处理View时,根据class name查询对应的Vie
wNManager,然后调用原生View的方法对View进行相应的操作。