首頁 文章 RN渲染原理1

RN渲染原理1

2024-06-15 22:17  瀏覽數:124  來源:许某    

上面我们也说了,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()方法。



聲明:以上文章均為用戶自行添加,僅供打字交流使用,不代表本站觀點,本站不承擔任何法律責任,特此聲明!如果有侵犯到您的權利,請及時聯系我們刪除。

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