“应用未注册”错误

了解应用未注册错误的含义以及如何在 Expo 或 React Native 应用中解决该错误。


在开发 Expo 或 React Native 应用时,经常会遇到类似这样的错误:

🌐 When developing an Expo or React Native app, it's common to run into an error that looks like:

Terminal
Application "main" has not been registered.# OrInvariant Violation: "main" has not been registered.

在这个特定的错误中,"main"可以是任意字符串。

🌐 In this particular error, "main" can be any string.

这个错误意味着什么

🌐 What this error means

异常可能会阻止你的应用自行注册

🌐 An exception may be preventing your app from registering itself

此错误最常见的原因是你的应用在能够注册自己之前就抛出了异常。当 React Native 应用加载时,有两个步骤:

🌐 The most common cause of this error is that there is an exception thrown in your application before it's able to register itself. When a React Native application loads, there are two steps:

  1. 加载 JavaScript 代码,如果一切成功,那么你的应用将会被注册。如果在加载包时出现任何异常,执行将被中止,并且永远不会执行到应用注册的部分。
  2. 运行已注册的应用。如果加载代码失败,则应用将不会被注册,并且你将看到本页面所述的错误。

如果你遇到这种情况,你看到的错误信息只是一个烟雾弹,它转移了你对导致应用未注册的真实错误的注意力。

🌐 If you're in this situation, the error message you're seeing is a red herring, it's distracting you from the real error that led to the application not being registered.

在此错误信息之前查看你的日志,看看可能造成它的原因。一个常见原因是多个本地模块依赖的版本注册为视图——例如这个 Stack Overflow 帖子,发帖者的依赖中有多个版本的 react-native-safe-area-context

🌐 Look at your logs before this error message to see what may have caused it. A frequent cause is multiple versions of a native module dependency that registers itself as a view — for example this Stack Overflow thread where the poster has multiple versions of react-native-safe-area-context in their dependencies.

你的应用根组件可能未注册

🌐 Your app root component may not be registered

另一种可能性是传递给 AppRegistry.registerComponentAppKey 与在原生 iOS 或 Android 端注册的 AppKey 不匹配。

🌐 Another possibility is that there is a mismatch between the AppKey being provided to AppRegistry.registerComponent, and the AppKey being registered on the native iOS or Android side.

在托管项目中,默认行为是使用 “main” 作为 AppKey。这一点会自动为你处理,只要你不将 package.json 中的 "main" 字段更改为默认值,这就会正常工作。如果你想自定义应用的入口点,请参阅 registerRootComponent API 参考。

🌐 In managed projects, the default behavior is to use "main" as the AppKey. This is handled for you automatically, and as long as you don't change the "main" field in your package.json from the default value then this will just work. If you want to customize the app entry point, see registerRootComponent API reference.

在包含原生代码的项目中,默认情况下,你会在你的 index.js 中看到类似这样的内容:

🌐 In projects with native code, you will see something like this in your index.js by default:

import { registerRootComponent } from 'expo'; import App from './App'; registerRootComponent(App);

其中 registerRootComponent 实现为:

🌐 where registerRootComponent is implemented as:

function registerRootComponent(component) { AppRegistry.registerComponent('main', () => component); }

在原生端的 AppDelegate.m 中,你应该看到:

🌐 And on the native side, in AppDelegate.m you should see:

RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"main" initialProperties:nil];

MainActivity.java 中:

🌐 and in MainActivity.java:

@Override protected String getMainComponentName() { return "main"; }

默认情况下,“main” 会在整个项目中一致使用。如果你遇到这个错误,可能是某些内容已经发生了变化,这些值不再一致。请确保你在 JavaScript 端注册的名称与本地端预期的名称一致(如果你使用的是 Expo 的 registerRootComponent 函数,那应该是“main”)。

🌐 By default, "main" is consistently used throughout the project. If you're running into this error, something has likely changed and these values no longer coincide. Ensure that the names you are registering on the JavaScript side are the ones expected on the native side (if you're using Expo's registerRootComponent function, that would be "main").

其他考虑因素

🌐 Other considerations

此错误也可能在其他一些情况下发生,但它的发生较难预测,修复方法会更针对你的项目。例如,其他一些情况包括:

🌐 This error can also occur in a few other scenarios, but it's less predictable and the fixes would be more specific to your project. For example, some other cases are:

  • 你正在连接到错误项目的本地开发服务器。尝试关闭其他 Expo CLI 或 React Native 社区 CLI 进程(可以用 ps -A | grep "expo\|react-native" 找到它们)。
  • 如果此错误只在你的生产应用中出现,那么尝试在本地以生产模式运行应用,并使用 npx expo start --no-dev --minify 来查找错误的来源。