跳到主要内容
新架构实战课 实操 + 基建 + 原理全维度包揽,抢先掌握 React Native 新架构精髓 立即查看 >

调试

开启调试的快捷键

React Native 在 iOS 模拟器上支持一些快捷键操作,具体会在下文中描述。要使用快捷键请务必确保模拟器的 Hardware 菜单中,Keyboard 选项下的"Connect Hardware Keyboard"处于开启状态,否则按键是没有响应的。

访问 App 内的开发菜单

你可以通过摇晃设备或是选择 iOS 模拟器的"Hardware"菜单中的"Shake Gesture"选项来打开开发菜单。另外,如果是在 iOS 模拟器中运行,还可以按下Command + D 快捷键,Android 模拟器对应的则是Command + M(windows 上可能是 F1 或者 F2),或是直接在命令行中运行adb shell input keyevent 82来发送菜单键命令。

在发布(production)版本中开发者菜单将无法使用。

Enabling Fast Refresh

Fast Refresh is a React Native feature that allows you to get near-instant feedback for changes in your React components. While debugging, it can help to have Fast Refresh enabled. Fast Refresh is enabled by default, and you can toggle "Enable Fast Refresh" in the React Native developer menu. When enabled, most of your edits should be visible within a second or two.

某些情况下自动刷新并不能顺利实施。如果碰到任何界面刷新上的问题,请尝试手动完全刷新。具体的操作就是在开发菜单中点击"Reload"选项。也可以在 iOS 模拟器中按下Command + R ,Android 模拟器上对应的则是按两下R

但有些时候你必须要重新编译应用(run-ios 或是 run-android)才能使修改生效:

  • 增加了新的资源(比如给 iOS 的Images.xcassets或是 Andorid 的res/drawable文件夹添加了图片)
  • 更改了任何的原生代码(objective-c/swift/java)

LogBox

Errors and warnings in development builds are displayed in LogBox inside your app.

LogBox 在发布版本(release/production)中是自动禁用的。

控制台的错误与警告提示

Console errors and warnings are displayed as on-screen notifications with a red or yellow badge, and the number of errors or warning in the console respectively. To view a console error or warnings, tap the notification to view the full screen information about the log and to paginiate through all of the logs in the console.

These notifications can be hidden using LogBox.ignoreAllLogs(). This is useful when giving product demos, for example. Additionally, notifications can be hidden on a per-log basis via LogBox.ignoreLogs(). This is useful when there's a noisy warning that cannot be fixed, like those in a third-party dependency.

Ignore logs as a last resort and create a task to fix any logs that are ignored.

import { LogBox } from 'react-native';

// Ignore log notification by message:
LogBox.ignoreLogs(['Warning: ...']);

// Ignore all log notifications:
LogBox.ignoreAllLogs();

未捕获的错误

Unhanded JavaScript errors such as undefined is not a function will automatically open a full screen LogBox error with the source of the error. These errors are dismissable and minimizable so that you can see the state of your app when these errors occur, but should always be addressed.

语法错误

Syntax errors will automatically open a full screen LogBox error with the source of the syntax error. This error is not dismissable because it represents invalid JavaScript execution that must be fixed before continuing with your app. To dismiss these errors, fix the syntax error and either save to automatically dismiss (with Fast Refresh enabled) or cmd+r to reload (with Fast Refresh disabled).

Chrome 开发者工具

在开发者菜单中选择"Debug JS Remotely"选项,即可以开始在 Chrome 中调试 JavaScript 代码。点击这个选项的同时会自动打开调试页面 http://localhost:8081/debugger-ui.(如果地址栏打开的是 ip 地址,则请自行改为 localhost)

在 Chrome 的菜单中选择Tools → Developer Tools可以打开开发者工具,也可以通过键盘快捷键来打开(Mac 上是Command + Option + I,Windows 上是Ctrl + Shift + I或是 F12)。打开有异常时暂停(Pause On Caught Exceptions)选项,能够获得更好的开发体验。

Note: on Android, if the times between the debugger and device have drifted; things such as animation, event behavior, etc., might not work properly or the results may not be accurate. Please correct this by running adb shell "date `date +%m%d%H%M%Y.%S%3N`" on your debugger machine. Root access is required for the use in real device.

注意:Chrome 中并不能直接看到 App 的用户界面,而只能提供 console 的输出,以及在 sources 项中断点调试 js 脚本。一些老的教程和文章会提到 React 的 Chrome 插件,这一插件目前并不支持 React Native,而且调试本身并不需要这个插件。不过你可以安装独立(非插件)版本的 React Developer Tools 来辅助查看界面布局,下文会讲述具体安装方法。

注意:使用 Chrome 调试目前无法观测到 React Native 中的网络请求,你可以使用功能更强大的第三方的react-native-debugger或是官方的flipper(注意仅能在 0.62 以上版本可用)来观测。

使用自定义的 JavaScript 调试器来调试

如果想用其他的 JavaScript 调试器来代替 Chrome,可以设置一个名为REACT_DEBUGGER的环境变量,其值为启动自定义调试器的命令。调试的流程依然是从开发者菜单中的"Debug JS Remotely"选项开始。

被指定的调试器需要知道项目所在的目录(可以一次传递多个目录参数,以空格隔开)。例如,如果你设定了REACT_DEBUGGER="node /某个路径/launchDebugger.js --port 2345 --type ReactNative",那么启动调试器的命令就应该是node /某个路径/launchDebugger.js --port 2345 --type ReactNative /某个路径/你的RN项目目录

以这种方式执行的调试器最好是一个短进程(short-lived processes),同时最好也不要有超过 200k 的文字输出。

Safari Developer Tools

你可以使用 Safari 来调试你的 iOS 版本的应用,而不必启用"Debug JS Remotely".

  • Enable Develop menu in Safari: Preferences → Advanced → Select "Show Develop menu in menu bar"
  • Select your app's JSContext: Develop → Simulator → JSContext
  • Safari's Web Inspector should open which has a Console and a Debugger

虽然默认情况下可能没有启用 source map,但您可以按照本指南Youtube 视频来启用 source map,并在源代码的正确位置设置断点。

然而,每次重新加载应用程序(使用实时重新加载,或通过手动重新加载)时,都会创建一个新的 JSContext。选择 "自动显示 JSContextts 的 Web 检查器(Automatically Show Web Inspectors for JSContexts)"可以帮你自动选择最新的 JSContext。

React Developer Tools

你可以使用独立版 React 开发者工具(不是 chrome 的插件)来调试 React 组件层次结构。要使用它,请全局安装react-devtools包:

注意:react-devtools v4 需要 react-native 0.62 或更高版本才能正常工作。

npm install -g react-devtools

译注:react-devtools 依赖于 electron,而 electron 需要到国外服务器下载二进制包,所以国内用户这一步很可能会卡住。此时请在环境变量中添加 electron 专用的国内镜像源:ELECTRON_MIRROR="https://npm.taobao.org/mirrors/electron/",然后再尝试安装 react-devtools。

安装完成后在命令行中执行react-devtools即可启动此工具:

react-devtools

React DevTools

很快就能连上模拟器。

提示:如果你不想全局安装react-devtools,可以把它单独加入项目中。用npm install --save-dev react-devtools命令把react-devtools包安装到你的项目中,并在package.jsonscripts中添加 "react-devtools": "react-devtools",接着在项目根目录下运行npm run react-devtools命令即可。

Integration with React Native Inspector

Open the in-app developer menu and choose "Toggle Inspector". It will bring up an overlay that lets you tap on any UI element and see information about it:

React Native Inspector

However, when react-devtools is running, Inspector will enter a collapsed mode, and instead use the DevTools as primary UI. In this mode, clicking on something in the simulator will bring up the relevant components in the DevTools:

React DevTools Inspector Integration

You can choose "Toggle Inspector" in the same menu to exit this mode.

Inspecting Component Instances

When debugging JavaScript in Chrome, you can inspect the props and state of the React components in the browser console.

First, follow the instructions for debugging in Chrome to open the Chrome console.

Make sure that the dropdown in the top left corner of the Chrome console says debuggerWorker.js. This step is essential.

Then select a React component in React DevTools. There is a search box at the top that helps you find one by name. As soon as you select it, it will be available as $r in the Chrome console, letting you inspect its props, state, and instance properties.

React DevTools Chrome Console Integration

性能监测

你可以在开发者菜单中选择"Pref Monitor"选项以开启一个悬浮层,其中会显示应用的当前帧数。


Debugging Application State

Reactotron is an open-source desktop app that allows you to inspect Redux or MobX-State-Tree application state as well as view custom logs, run custom commands such as resetting state, store and restore state snapshots, and other helpful debugging features for React Native apps.

You can view installation instructions in the README. If you're using Expo, here is an article detailing how to install on Expo.

原生端调试

访问控制台日志

在运行 RN 应用时,可以在终端中运行如下命令来查看控制台的日志:

$ npx react-native log-ios
$ npx react-native log-android

此外,你也可以在 iOS 模拟器的菜单中选择Debug → Open System Log...来查看。如果是 Android 应用,无论是运行在模拟器或是真机上,都可以通过在终端命令行里运行adb logcat *:S ReactNative:V ReactNativeJS:V命令来查看。

If you're using Create React Native App, console logs already appear in the same terminal output as the packager.

使用 Chrome 开发者工具来在设备上调试

If you're using Create React Native App, this is configured for you already.

对于 iOS 真机来说,需要打开 RCTWebSocketExecutor.m文件,然后将其中的"localhost"改为你的电脑的 IP 地址,最后启用开发者菜单中的"Debug JS Remotely"选项。

对于 Android 5.0+设备(包括模拟器)来说,将设备通过 USB 连接到电脑上后,可以使用adb命令行工具来设定从设备到电脑的端口转发:

adb reverse tcp:8081 tcp:8081

如果设备 Android 版本在 5.0 以下,则可以在开发者菜单中选择"Dev Settings - Debug server host for device",然后在其中填入电脑的”IP 地址:端口“。

如果在 Chrome 调试时遇到一些问题,那有可能是某些 Chrome 的插件引起的。试着禁用所有的插件,然后逐个启用,以确定是否某个插件影响到了调试。

调试原生代码

在和原生代码打交道时(比如编写原生模块),可以直接从 Android Studio 或是 Xcode 中启动应用,并利用这些 IDE 的内置功能来调试(比如设置断点)。这一方面和开发原生应用并无二致。