Home Article Practice RN渲染原理1

RN渲染原理1

2024-06-15 22:17  views:123  source:许某    

上面我们也说了,RN页面的入口一般是AppRegistry.js,我们就从这个页面入手开始分析RN页面的渲染流
程。先看一下RN页面的渲染流程序列图,如下所示:这个流程比较长,其实主要是方法的调用链多,原理还是很简单的,我
们先概括性的总结一下:React Native将代码由JSX转化为JS组件,启动过程中利用instantiat
eReactComponent将ReactElement转化为复合组件ReactCompositeCompon
ent与元组件ReactNativeBaseComponent,利用ReactReconciler对他们进行渲
染。UIManager.js利用C++层的Instance.cpp将UI信息传递给UIManagerModul
e.java,并利用UIManagerModule.java构建UI。UIManagerModule.java
接收到UI信息后,将UI的操作封装成对应的Action,放在队列中等待执行。各种UI的操作,例如创建、销毁、更
新等便在队列里完成,UI最终得以渲染在屏幕上。3.1 JavaScript层组件渲染如上图所示AppRegis
try.registerComponent用来注册组件,在该方法内它会调用AppRegistry.runApp
lication()来启动js的渲染流程。AppRegistry.runApplication()会将传入的C
omponent转换成ReactElement,并在外面包裹一层AppContaniner,AppContan
iner主要用来提供一些debug工具(例如:红盒)。如下所示:复制代码function renderAppl
ication<Props: Object>( RootComponent: ReactClass<Prop
s>, initialProps: Props, rootTag: any) { invariant(
rootTag, 'Expect to have a valid rootTag, instead
got ', rootTag ); ReactNative.render( <AppContain
er rootTag={rootTag}> <RootComponent {...in
itialProps} rootTag={rootTag} /> </AppCo
ntainer>, rootTag );}我们抛开函数调用链,分析其中关键的部分,其他部分都是简单的函
数调用。ReactNativeMount.renderComponent()instantiateReactC
omponent.instantiateReactComponent(node, shouldHaveDebu
gID)ReactNativeMount.renderComponent()复制代码 /** * @pa
ram {ReactComponent} instance Instance to render. * @
param {containerTag} containerView Handle to native vie
w tag */ renderComponent: function( nextElement:
ReactElement<*>, containerTag: number, callback?:
?(() => void) ): ?ReactComponent<any, any, any> {
//将RectElement使用相同的TopLevelWrapper进行包裹 var nextWra
ppedElement = React.createElement( TopLevelWrapper
, { child: nextElement } ); var topRootNodeI
D = containerTag; var prevComponent = ReactNativeMou
nt._instancesByContainerID[topRootNodeID]; if (prevC
omponent) { var prevWrappedElement = prevComponent
._currentElement; var prevElement = prevWrappedEle
ment.props.child; if (shouldUpdateReactComponent(p
revElement, nextElement)) { ReactUpdateQueue.enq
ueueElementInternal(prevComponent, nextWrappedElement,
emptyObject); if (callback) { ReactUpda
teQueue.enqueueCallbackInternal(prevComponent, callback
); } return prevComponent; } else {
ReactNativeMount.unmountComponentAtNode(containe
rTag); } } if (!ReactNativeTagHandles.reactT
agIsNativeTopRootID(containerTag)) { console.error
('You cannot render into anything but a top root');
return null; } ReactNativeTagHandles.assertRoot
Tag(containerTag); //检查之前的节点是否已经mount到目标节点上,如果有则进行比较
处理 var instance = instantiateReactComponent(nextWrap
pedElement, false); ReactNativeMount._instancesByCon
tainerID[containerTag] = instance; // The initial re
nder is synchronous but any updates that happen during
// rendering, in componentWillMount or componentDidM
ount, will be batched // according to the current ba
tching strategy. //将mount任务提交给回调Queue,最终会调用ReactReco
nciler.mountComponent() ReactUpdates.batchedUpdates(
batchedMountComponentIntoNode, instance,
containerTag ); var component = instance.getPub
licInstance(); if (callback) { callback.call(co
mponent); } return component; },该方法主要做了以下事情:将传入的
RectElement使用相同的TopLevelWrapper进行包裹,生成nextWrappedElemen
t。检查之前的节点是否已经mount到目标节点上,如果有则进行比较处理,将上一步生成的nextWrappedE
lement传入instantiateReactComponent(nextWrappedElement, f
alse)方法。将mount任务提交给回调Queue,最终会调用ReactReconciler.mountCo
mponent(),ReactReconciler.mountComponent()又会去调用C++层Inst
ance::mountComponent()方法。



Disclaimer: The above articles are added by users themselves and are only for typing and communication purposes. They do not represent the views of this website, and this website does not assume any legal responsibility. This statement is hereby made! If there is any infringement of your rights, please contact us promptly to delete it.

字符:    改为:
去打字就可以设置个性皮肤啦!(O ^ ~ ^ O)