1. RN Compoent 转 Native
1.1. RN
1.1.1. AppContainer
?
1.1.2. AppRegistry
registerComponent
/**
 注册组件
 从组件的 props 获取 runApplication 传过来的参数。
 @param appKey 组件 Key
 @param componentProvider 组件 Class
 */
static registerComponent(appKey, componentProvider, section?)
原生可能通过 appKey 得到相应原生 View
runApplication
/*
 启动 appKey 对应的组件
 @param appKey 组件 Key
 @param appParameters 传给组件的参数
 */
static runApplication(appKey, appParameters)
原生的 RCTRootView 在加载成功后会调用
unmountApplicationComponentAtRootTag
// 注销已经启动的组件
static unmountApplicationComponentAtRootTag(rootTag)
原生的 RCTRootContentView 在注销时会调用
1.2. iOS
1.2.1. RCTBridge
实现部分大部分在 RCTCxxBridge
/**
初始化 RCTBridge
这里会初始化所有原生模块。
@param delegate 获取 bundleURL 的代理
@param launchOptionslaunchOptions 启动参数
*/
- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate
                   launchOptions:(NSDictionary *)launchOptions;
/**
初始化 RCTBridge 【弃用】
这里会初始化所有原生模块。
@param bundleURL bundle 包
@param launchOptionslaunchOptions 启动参数
*/
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
                   moduleProvider:(RCTBridgeModuleListProvider)block
                    launchOptions:(NSDictionary *)launchOptions;
/**
异步调用原生模块提供的方法
通过回调获取结果
*/
- (void)enqueueJSCall:(NSString *)module method:(NSString *)method args:(NSArray *)args completion:(dispatch_block_t)completion;
/**
同步执行原生模块里的方法
直接返回结果
*/
- (JSValue *)callFunctionOnModule:(NSString *)module
                           method:(NSString *)method
                        arguments:(NSArray *)arguments
                            error:(NSError **)error;
1.2.2. RCTRootView
// 对应 AppRegistry.registerComponent 的 appKey
@property (nonatomic, copy, readonly) NSString *moduleName;
// 初始化参数,最终会传给 AppRegistry.registerComponent 注册的组件
@property (nonatomic, copy, readwrite) NSDictionary *appProperties;
// JS 加载阶段的 placeholder view,默认为 nil,可以设值
@property (nonatomic, strong) UIView *loadingView;
// 隐藏 loadingView 的延时,默认 0.25
@property (nonatomic, assign) NSTimeInterval loadingViewFadeDelay;
// 隐藏 loadingView 的持续时间,默认 0.25
@property (nonatomic, assign) NSTimeInterval loadingViewFadeDuration;
/**
创建有多个 RootView 的工程时用下面的初始化方法
@param initialProperties 初始化参数,最终会传给 AppRegistry.registerComponent 注册的组件
*/
- (instancetype)initWithBridge:(RCTBridge *)bridge
                    moduleName:(NSString *)moduleName
             initialProperties:(NSDictionary *)initialProperties
/**
创建只有一个 RootView 的工程时用下面的初始化方法
*/
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
                       moduleName:(NSString *)moduleName
                initialProperties:(NSDictionary *)initialProperties
                    launchOptions:(NSDictionary *)launchOptions
RCTRootView 加载过程:
- RCTJavaScriptDidLoadNotification JS Bundle 下载成功
 - RCTBridgeDidDownloadScriptNotification JS 加载成功
 - RCTDidInitializeModuleNotification 每个原生模块加载成功
 - 所有原生模块加载成功就可以当成功处理。
 
1.2.3. 过程
- RN 
AppRegistry.registerComponent注册多个 Component - 初始化唯一的 
RCTBridge - 初始化多个包含 
RCTRootView的ViewController 
1.3. Android
1.3.1. ReactRootView
private void defaultJSEntryPoint() {
  // ...
  // 调用 JS 的 AppRegistry.runApplication 方法
  catalystInstance.getJSModule(AppRegistry.class).runApplication(jsAppModuleName, appParams);
}
1.4. 原生直接调用 RN 的 JS 方法
RN 注册 Class.method 方法
const method = () => {
  // do some thing
}
BatchedBridge.registerCallableModule('Class', {
  method
});
iOS 调用 RN 注册的 Class.method 方法
[bridge enqueueJSCall:@"Class"
               method:@"method"
                 args:nil
          completion:nil];
Android 调用 RN 注册的 Class.method 参考 https://github.com/facebook/react-native/blob/59aada873e13bf0b1f5e3a10cfe9a5a45c28f9fb/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java#L492
String jsAppModuleName = getJSModuleName();
catalystInstance.getJSModule(Class.class).method(jsAppModuleName, null);