乐于分享
好东西不私藏

AppRegistry注册机制

AppRegistry注册机制

学完本章后,你能说出:

  • registerComponent 和 runApplication 的关系
  • 为什么 appKey 必须匹配
  • Expo 项目的注册点在哪里

AppRegistry 的两个核心方法

// AppRegistry.js(React Native JS 层)// ========== 方法 1:注册根组件(JS 调用)==========export function registerComponent(    appKeystring,    getRootComponent: () => React.ComponentType) {    // 存到 Native 可访问的注册表    modules[appKey] = getRootComponent    registerCallableModule(appKey, getRootComponent)}// ========== 方法 2:运行应用(Native 调用)==========export function runApplication(appKeystringappParametersany) {    const RootComponent = modules[appKey]    if (!RootComponent) {        // 错误:appKey 不匹配!        throw new Error(            `App with appKey "${appKey}" is not registered. ` +            `Did you forget to call AppRegistry.registerComponent?`        )    }    // 触发 React render    renderApplication(RootComponent, appParameters)}

Expo 项目的注册点

// node_modules/expo-router/entry.js// Expo 项目的真正入口文件import { AppRegistry } from 'react-native'// registerRootComponent 内部执行:AppRegistry.registerComponent('main'() => {    // 返回 expo-router 的根组件    return require('expo-router/src/view/EntryRoute').default})// 实际等价于:// AppRegistry.registerComponent('main', RootComponent)

为什么 appKey 必须匹配?

【正确情况】Native: moduleName = "main" 或 getMainComponentName() = "main"JS:    AppRegistry.registerComponent('main', ...)                    ↓           Native 调用 runApplication("main", ...)                    ↓           JS 注册表中找到 "main" → 渲染 ✓【错误情况】Native: moduleName = "MyApp"JS:    AppRegistry.registerComponent('main', ...)                    ↓           Native 调用 runApplication("MyApp", ...)                    ↓           JS 注册表中只有 "main" → 找不到!                    ↓           崩溃 ❌

验证

# 验证 1:找到 expo-router 的 registerComponent 调用cat node_modules/expo-router/entry.js# 验证 2:确认 Android appKeygrep -n "main" android/app/src/main/java/com/yourapp/MainActivity.kt# 验证 3:确认 iOS appKey(Swift AppDelegate)grep -n "moduleName" ios/YourApp/AppDelegate.swift# 或grep -n '"main"' ios/YourApp/AppDelegate.swift# 验证 4:确认 iOS AppDelegate 是 Swift(不是 .mm)find ios -name "AppDelegate.swift"find ios -name "AppDelegate.mm"   # 旧版项目才有,新版应无输出# 验证 5:模拟 appKey 错误# 修改 iOS AppDelegate.swift 的 moduleName 为 "wrong"# 或修改 Android MainActivity.kt 的 getMainComponentName() 返回 "wrong"# 运行 App,观察崩溃日志# 错误信息应为:"App with appKey "wrong" is not registered"