You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RN 0.78新架构下RCTAppDelegate.bridge始终为nil,无法复用Turbo Module注册表

React Native 0.78新架构下复用主Bridge加载动态Bundle解决方案

问题根源

RN 0.78的新架构中,RCTAppDelegate不再直接暴露可用的bridge实例——原来的self.bridge属性在调用super.application后仍为nil,因为新架构的Bridge初始化逻辑被封装到了内部的bridgeManager中,初始化流程是延迟完成的。新建RCTBridge会生成独立的Turbo Module注册表,无法共享主应用已注册的Native模块(如DeviceInfo),进而触发崩溃。

可靠获取主Bridge实例的方案

通过重写RCTAppDelegate的createBridgeWithDelegate方法,在Bridge创建的第一时间捕获实例并保存,这是官方初始化流程中最可靠的时机:

final class AppDelegate: RCTAppDelegate {
    // 保存主应用的活跃Bridge实例
    var sharedBridge: RCTBridge?

    override func createBridgeWithDelegate(_ delegate: RCTBridgeDelegate?, launchOptions: [AnyHashable : Any]?) -> RCTBridge {
        let bridge = super.createBridgeWithDelegate(delegate, launchOptions: launchOptions)
        // 在这里捕获桥接实例,此时Bridge已完成初始化
        self.sharedBridge = bridge
        return bridge
    }

    override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]?) -> Bool {
        self.moduleName = AppLaunchConstants.moduleName
        self.dependencyProvider = RCTAppDependencyProvider()
        self.initialProps = [:]
        
        let result = super.application(application, didFinishLaunchingWithOptions: launchOptions)
        return result
    }

    // 实现RCTBridgeDelegate的必要方法
    func sourceURL(for bridge: RCTBridge!) -> URL! {
        return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
    }
}

复用主Bridge加载新Bundle

直接使用保存的sharedBridge加载新bundle,无需新建Bridge,这样就能复用主应用的Turbo Module注册表:

func loadJsBundle(with url: URL) {
    guard let app = UIApplication.shared.delegate as? AppDelegate,
          let mainBridge = app.sharedBridge else {
        print("无法获取主Bridge实例")
        return
    }

    // 更新Bridge的bundleURL为新bundle地址
    mainBridge.bundleURL = url
    
    // 通知JS侧即将加载新代码
    NotificationCenter.default.post(name: NSNotification.Name.RCTJavaScriptWillStartLoading, object: nil)
    
    // 触发Bridge重新加载JS代码
    mainBridge.reload()
    
    // 若需创建新RootView,复用同一个Bridge
    let newRootView = RCTRootView(bridge: mainBridge, moduleName: "NewBundleRootComponent", initialProperties: nil)
    // 将newRootView设置为当前视图控制器的view或导航栈根视图
}

关键注意事项

  • 新bundle的RN版本必须与主应用完全一致,避免Native模块兼容问题
  • 加载新bundle前建议清理JS侧全局状态,避免新旧代码状态冲突
  • 若使用Fabric新UI架构,需用FabricRootView替代RCTRootView,并确保新bundle支持Fabric

内容的提问来源于stack exchange,提问作者Sohini Acharya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 03:07:35