IMG_5907.JPG

  • 前言->React Native与传统的HybirdApp最大的区别就是抛开WebView,使用JSC+原生组件的方式进行渲染

    整体框架

  • React与React Native的原理是相同的,都是由JavaScript实现的虚拟DOM来驱动页面View的渲染,只不过React.js驱动HTML DOM的渲染,RN是驱动iOS、Android原生组件的渲染

未命名文件 (40).jpg

前端页面开发及渲染

  • 准备阶段由原来承担大部分工作,包括启动JS运行环境,创建空白画布,实例化自定义module及导出各种可控JS使用的API等。
  • 渲染阶段的主要职责包括根据注册信息创建实际视图、维护虚拟dom树、维护待渲染队列及对布局样式进行转换等。

未命名文件 (41).jpg

(1)JS入口

  • 将当期APP的对象注册到AppRegistry组件中,AppRegistry组件是js moudle。 ```javascript import { AppRegistry } from “react-native”; import App from “./src/index”;

AppRegistry.registerComponent(“Wubacst”, () => App);

  1. <a name="BQXEx"></a>
  2. ### (2)RN AppRegistry
  3. - **AppRegistry 是运行所有React Native应用程序的js入口点**
  4. - **应用程序跟组件需要通过AppRegistry.registerComponent来注册他们自身**
  5. - **然后本地系统就可以加载应用程序的包,再然后当AppRegistry.runApplication准备就绪后就可以真正的运行该应用程序了**
  6. - **AppRegistry在require序列里是required,确保在其他模块被需求之前js执行环境已经被required**
  7. ```javascript
  8. //static静态方法,用来注册配置信息
  9. static **registerConfig**(config: Array<AppConfig>)
  10. //static静态方法,注册组件
  11. static **registerComponent**(appKey: string, getComponentFunc: Function)
  12. //static静态方法,注册线程
  13. static **registerRunnable**(appKey: string, func: Function)
  14. //static静态方法,进行运行应用
  15. static **runApplication**(appKey: string, appParameters: any)
  16. runApplication: function runApplication(appKey, appParameters) {
  17. var msg = 'Running application "' + appKey + '" with appParams: ' + JSON.stringify(appParameters) + '. ' + '__DEV__ === ' + String(__DEV__) + ', development-level warning are ' + (__DEV__ ? 'ON' : 'OFF') + ', performance optimizations are ' + (__DEV__ ? 'OFF' : 'ON');
  18. infoLog(msg);
  19. BugReporting.addSource('AppRegistry.runApplication' + runCount++, function () {
  20. return msg;
  21. });
  22. invariant(runnables[appKey] && runnables[appKey].run, 'Application ' + appKey + ' has not been registered.\n\n' + "Hint: This error often happens when you're running the packager " + '(local dev server) from a wrong folder. For example you have ' + 'multiple apps and the packager is still running for the app you ' + 'were working on before.\nIf this is the case, simply kill the old ' + 'packager instance (e.g. close the packager terminal window) ' + 'and start the packager in the correct app folder (e.g. cd into app ' + "folder and run 'npm start').\n\n" + 'This error can also happen due to a require() error during ' + 'initialization or failure to call AppReg
  23. istry.registerComponent.\n\n');
  24. SceneTracker.setActiveScene({
  25. name: appKey
  26. });
  27. runnables[appKey].run(appParameters);
  28. }

(3)ReactDOM.render

  • ReactDOM.render是React的最基本方法用于将模板转为HTML语言,并插入指定的DOM节点

    1. ReactDOM.render(
    2. <Page />,
    3. document.getElementById('app')
    4. );

    (4)RN组件的生命周期

  • 像Android和iOS开发一样,React Native中的组件也有生命周期

  • 当应用启动时,React Native在内存中维护着一个虚拟DOM,组件的生命周期就是指组件初始化并挂载到虚拟DOM为开始,到组件从虚拟DOM卸载为终结。生命周期的方法就是组件在虚拟DOM中不同状态的描述。
  • 组件的生命周期分为三个阶段:
    • 挂载
    • 更新
    • 卸载

未命名文件 (45).jpg

—>挂载

  • 挂载指的是组件的实例被创建并插入到DOM中,调用方法:

    1. constructor(props) {
    2. super(props);
    3. this.state = {
    4. text: '构造方法'
    5. };
    6. }
  • constructor是RN组件的构造方法,它在RN组件被加载前先被调用。当我们的组件继承自React.Component时,需要在构造方法中最先调用super(props)。如果不需要初始化state,则不需要实现构造方法。

  • ComponentWillMount方法在挂载前被立即调用。它在render方法前被执行,因此,在ComponentWillMount方法中设置state并不会导致重新被渲染。它只执行一次渲染,render方法中不应该修改组件的props和state,render方法在更新阶段也会被调用,前提是shouldComponentUpdate 方法返回true。
  • ComponentDidMount方法在组件被挂载后立即调用,在render方法后执行,可以在这个方法中获取其中的元素或者子组件,需要注意的是,子组件ComponentDidMount方法会在父组件的ComponentDidMount方法之前调用,如果需要从网络加载数据显示到界面上,最好在这里进行网络请求。在ComponentDidMount方法中设置state将被重新渲染。

    —>组件更新

    —>卸载

  • 卸载就是从DOM中删除组件,会调用如下方法

    (5)React Native如何把React转化为元素的API

    • React Native会在一开始生成OC模块表,然后把这个模块表传入JS中,JS参照模块表,就能间接调用OC代码。
    • 相当于买了一个机器人(OC),对应一份说明书(模块表),用户(JS)参数说明书去执行机器人的操作

      (6)React Native如何做到JS与OC交互

    • iOS原生API有个JavaScriptCore框架,通过它就能实现JS和OC交互

      1. 首先写好前端的jsx代码
      2. 把jsx代码解析成JavaScript代码
      3. OC读取JS文件
      4. 把JavaScript读取出来,利用JavaScriptCore执行
      5. JavaScript代码返回一个数组,数组中会描述OC对象,OC对象的属性,OC对象所需要执行的方法,这样就能让这个对象设置属性,并且调用方法

未命名文件 (46).jpg

(7)RN通信机制

  • OC生成一张模块配置表,包含所有模块和模块里的方法,根据特定的标识宏(RCT_EXPORT_MODULE()),将可以暴露的方法暴露给JS。
  • OC-JS交互流程

未命名文件 (47).jpg