如何解决React Native中的常见错误(附代码示例)

1,373 阅读10分钟

React Native是当今使用最多的JavaScript移动框架之一。React Native使熟悉JavaScript和React网络框架的开发者能够使用类似的方法和原则开发移动应用程序。

作为一个React Native开发者,你在开发应用程序时一定会遇到一些错误。当编译器在运行代码时检测到错误,它会终止进程并显示错误信息。

React Native中的错误信息是非常具有描述性的。它们告诉开发者发生了什么错误以及在哪里检测到错误。此外,他们经常提供明确的指示或至少提供如何解决问题的线索。

有些错误本来就比其他错误更容易调试。例如,由于使用错误的语法或访问未定义的变量或组件而发生的错误,比由错误配置或不兼容的依赖关系造成的错误更容易调试。

无论错误的性质如何,你经常需要帮助来解决它们。

在这篇文章中,我将介绍一些常见的React Native错误和它们的解决方案。其中一些错误会有不同的解决方案,这取决于首先是什么原因导致的错误。对于这样的错误,请一个接一个地看解决方案。

安装应用程序失败

在创建了一个新的React Native项目后,当试图用命令react-native run-android ,第一次运行该应用时,你可能会遇到以下错误:

BUILD FAILED in 13s

error Failed to install the app. Make sure you have an Android emulator running or a device connected. Run CLI with --verbose flag for more details.
Error: Command failed: ./gradlew app:installDebug -PreactNativeDevServerPort=8081

FAILURE: Build failed with an exception.
...

这个错误信息说的是构建过程没有成功,还指定了失败的特定命令。有时你可以通过简单地使用新的命令提示和重新启动虚拟设备来摆脱这个错误。

然而,很多时候,这个错误是由于使用不兼容的Gradle版本来构建应用程序造成的。

Android studio构建系统需要正确的Gradle版本来成功构建Android应用程序。在这种情况下,你需要将应用中使用的Gradle版本升级到与Android studio构建系统兼容的版本。

遵循这些步骤:

  1. 在VS Code等文本编辑器中打开你的React Native应用程序
  2. 在应用程序的根文件夹中,导航到android > gradle > wrapper
  3. 编辑gradle-wrapper.properties 文件
  4. 用兼容版本的Gradle的URL来更新distributionUrl 变量
  5. 再次运行react-native run-android ,使用新版本构建应用程序。

这里是第二和第三步的完整路径:

{your-project-folder}\android\gradle\wrapper\gradle-wrapper.properties

要为第四步获得准确的Gradle版本,请到Gradle的分发列表中,检查最新的-all.zip Gradle版本。然后,按以下方法更新distributionUrl 变量:

distributionUrl=https\://services.gradle.org/distributions/gradle-{latest version}.zip

要了解更多关于Gradle和Android studio的信息,请阅读Android Gradle插件和Android Studio兼容性文章。

无法加载脚本

开发者在尝试运行他们的React Native应用程序时,通常会遇到另一个错误,如下图所示:

Unable to load script. Make sure you're either running a metro server (run 'react-native start') or that your bundle 'index.android.bundle' is packaged correctly for release.

这个错误总是显示在连接的Android设备上。造成这个错误的原因有几个。因此,也有不同的解决方案。

解决方案1:正确打包捆绑

你的应用程序的所有JavaScript都被捆绑在index.android.bundle 文件中。如果捆绑文件不可用或没有正确打包,你会得到Unable to load script 错误。按照下面的指示来解决这个问题。

进入{your-project-folder}/android/app/src/main/ 文件夹,检查其中是否存在一个assets 文件夹。如果assets文件夹不在那里,就创建它。

接下来,直接从你的根文件夹,运行这个:

cd android
./gradlew clean

接下来,打开一个命令终端,确保它指向你的项目的根文件夹。如果你的项目只有一个文件(即index.js ),运行以下命令:

react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res

如果有两个文件(即index.android.jsindex.ios.js ),则运行以下命令:

react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res

注意,这两条都是单一的命令。

在生成捆绑包后,运行react-native run android

要一次性执行上述所有步骤,你可以像这样把它们放在package.json的scripts 部分:

"android-script": "react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --assets-dest android/app/src/main/res && react-native run-android"

上面的命令是npm run android-script

解决方案2:使用adb reverse

如果你在执行第一个解决方案后一直得到同样的错误,那么你需要考虑其他原因。另一个常见的原因是,端口没有暴露。如果你在一个物理设备上运行你的应用程序,就会发生这种情况。

adb reverse 命令可以让你在你的安卓设备上暴露一个TCP端口与你电脑上的TCP端口。要尝试修复这个错误,运行以下命令:

adb reverse tcp:8081 tcp:8081

这里你通过电脑上的端口8081暴露手机上的TCP端口。

如果你的WindowsPATH 变量中没有Android平台工具组件,那么adb 可执行文件在以下路径找到:

C:\Users\{your-username}\AppData\Local\Android\sdk\platform-tools

解决方案3:增加明文支持

如果前两个方案不能解决React Native无法加载脚本的问题,那么这个错误很可能是来自于网络通信问题。

具体来说,很可能是由于明文支持被禁用而导致应用程序无法从开发服务器上访问,从Android 9.0(API级别28)开始就是如此。

要解决这个问题,请修改AndroidManifest.xml 文件并添加明文支持,如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <uses-permission android:name="android.permission.INTERNET" />
    <application
        ...
        android:usesCleartextTraffic="true"
        ...>
        ...
    </application>
</manifest>

你可以在AndroidManifest.xml 文件中找到你的文件:

{your-project-folder}/android/app/src/main/AndroidManifest.xml

重新启动你的应用程序,以便应用该变化。

React Nativerun-android 命令未被识别

有时候,当你试图在Android上运行你的React Native应用程序时,你可能会在命令提示符上得到以下错误信息:

Command run-android unrecognized. Did you mean to run this inside a react-native project?

该错误信息已经提示了最常见的错误原因:你没有在React Native文件夹中运行该命令。在这种情况下,解决方案是简单地确保你在运行应用程序之前导航到你的应用程序的根文件夹。这就是我的意思:

// After initializing a project:
react-native init AwesomeProject

// Make sure to navigate to the project folder:
cd AwesomeProject

// Before you run the app:
react-native run-android

否则,如果错误不是因为使用了错误的文件夹,那么就有可能是你没有安装项目的内容。要做到这一点,请运行:

npm install or yarn install

也有可能是你的 react-native 或 react-native-cli 的全局安装已经过时或损坏。在这种情况下,只需使用以下命令之一在全局范围内重新安装你的库:

npm:

npm install -g react-native && npm install -g @react-native-community/cli

Yarn:

yarn global add react-native && yarn global add @react-native-community/cli

注意,我建议使用npx(包含在npm v5.0+中)来按需安装库。

这意味着每当你运行npx react-native init <your-project-name> 或任何其他React Native CLI命令时,它都会在创建项目前首先询问你是否允许安装react-native 。这可以确保你在任何时候都使用最新的版本!

最后,如果上述所有的方法都不奏效,你可能需要用下面的命令来升级你的npm:

npm install npm@latest -g

确保你使用一个新的终端来运行这些命令中的每一个。这是为了防止在你的.bashrc 文件中使用过时的路径源。

react-native 命令未找到

command not found: react-native 是React Native中另一个常见的错误。当你试图运行任何 命令时,你会遇到这个错误,比如你试图初始化React Native项目,像这样。react-native

react-native init MyProject

command not found 错误有两个潜在的原因:要么你的本地机器上没有安装CLI,要么你有,但没有正确配置。

这两种情况都可以通过对所有npm可执行文件使用npx来避免。例如,要创建一个新的React Native应用,用npx运行它,如下所示:

npx react-native init MyProject

这将在初始化项目之前安装最新的可用版本的react-native 包。

未识别的命令:"link"

当试图在React Native项目中链接自定义字体或图标等资产时,你可能会在命令终端上得到以下错误:

error Unrecognized command "link". info Run "react-native --help" to see a list of all available commands.

当你试图使用手动链接功能(即react-native linkreact-native link unlink 命令)时,这个错误就会发生,在React Native 0.69中已经删除,取而代之的是自动链接。

为了避免这个错误,你需要使用第三方资产链接库,如 [react-native-asset](https://www.npmjs.com/package/react-native-asset)来自动链接资产。

首先,用以下命令之一安装库:

npm install -g react-native-asset
# or if you're using yarn: 
yarn global add react-native-asset

然后在项目文件夹的根层创建一个react-native.config 文件,并添加以下代码片段:

module.exports = {
    project: {
        ios: {},
        android: {}
    },
    "assets": [
      "./src/assets/font",
      "./src/assets/mp3",
      "./src/assets/icons"
  ]
};

运行下面的一个命令,在你的代码库中启用自动链接和解除链接。

npm:

npx react-native-asset

yarn:

yarn react-native-asset

现在你可以在你的代码中使用任何指定的资产。例如,你可以在你的样式表中使用一个自定义字体。

fontFamily: 'my-custom-font'

重复的资源

当你试图使用Generate Signed APK ,从Android Studio生成一个发布的APK时,你可能面临的另一个常见错误是重复资源错误。

[drawable-mdpi-v4/jumper] /Users/admin/Projects/testApp/android/app/src/main/res/drawable-mdpi/jumper.png [drawable-mdpi-v4/jumper] /Users/admin/Projects/testApp/android/app/build/generated/res/react/release/drawable-mdpi-v4/jumper.png: Error: Duplicate resources
:app:mergeReleaseResources FAILED

FAILURE: Build failed with an exception.

...

因为在Android文件夹内的Android项目中发现了重复的资源,所以发生了构建失败。根据不同的原因,有多种解决方案。

解决方案1:从终端清理drawable文件夹

很多时候,你可以通过使用Gradle从终端清理drawable 文件夹来摆脱这个错误。要做到这一点,cdandroid 文件夹,然后在试图再次运行应用程序之前运行./gradlew clean

react-native run android

如果失败,请尝试下一个解决方案。

解决方案2:添加一些辅助代码

大多数时候,简单地清理drawable 文件夹并不能解决这个问题。如果是这种情况,那么你就需要在react.gradle 文件中稍作修改,以防止重复资源碰撞。

node_modules/react-native/react.gradle 中找到的react.gradle 文件中添加以下辅助代码。这段代码应该放在doFirst 块的后面:

doLast {
    def moveFunc = { resSuffix ->
        File originalDir = file("$buildDir/generated/res/react/release/drawable-${resSuffix}");
        if (originalDir.exists()) {
            File destDir = file("$buildDir/../src/main/res/drawable-${resSuffix}");
            ant.move(file: originalDir, tofile: destDir);
        }
    }
    moveFunc.curry("ldpi").call()
    moveFunc.curry("mdpi").call()
    moveFunc.curry("hdpi").call()
    moveFunc.curry("xhdpi").call()
    moveFunc.curry("xxhdpi").call()
    moveFunc.curry("xxxhdpi").call()
}

这个错误在2018年被GitHub用户echaso解决了,他提供了上面的代码

总结

在这篇文章中,我们看了React Native中的六个常见错误,以及这些错误的每一个都可以被调试出来。如果你遇到的错误没有包括在这里,不要犹豫,请查看这篇文章,了解可能的解决方案

总之,感谢您的阅读,下次见