@react-navigation/drawer致React Native Chrome调试崩溃修复方法
问题背景
当前开发环境为react-navigation 6.x搭配react-native 0.68.2,项目依赖配置如下:
/* package.json */ "dependencies": { "@react-navigation/drawer": "^6.4.1", "@react-navigation/native": "^6.0.10", "react": "17.0.2", "react-native": "0.68.2", "react-native-gesture-handler": "^2.4.2", "react-native-reanimated": "^2.8.0", "react-native-safe-area-context": "^4.3.1", "react-native-screens": "^3.13.1" }
项目入口index.js内容:
/* index.js */ import 'react-native-gesture-handler'; import {AppRegistry} from 'react-native'; import App from './App'; import {name as appName} from './app.json'; import { AppScreens } from './app/AppScreens'; AppRegistry.registerComponent(appName, () => AppScreens);
导航实现文件AppScreens.tsx初始代码:
/* AppScreen.tsx */ import React from 'react'; import { createDrawerNavigator } from '@react-navigation/drawer'; import { FirstScreen } from './FirstScreen'; import { SecondScreen } from './SecondScreen'; import { NavigationContainer } from '@react-navigation/native'; const Drawer = createDrawerNavigator(); export const AppScreens = () => { return ( <NavigationContainer> <Drawer.Navigator> <Drawer.Screen name="FirstScreen" component={FirstScreen} /> <Drawer.Screen name="SecondScreen" component={SecondScreen} /> </Drawer.Navigator> </NavigationContainer> ) }
异常现象
项目非调试模式下运行完全正常,开启Chrome调试时会触发两类报错:
Calling synchronous methods on native modules is not supported in chrome Consider providing alternative methods to expose this method in debug mode, e.g. by exposing constants ahead-of-time.Cannot read properties of undefined (reading 'AppScreens')
经排查,问题定位在const Drawer = createDrawerNavigator();代码行:即使移除所有抽屉导航的使用逻辑,仅保留该行初始化代码仍会触发报错;注释该行后Chrome调试即可恢复正常。
问题产生原因
@react-navigation/drawer6.x版本强依赖react-native-reanimated,执行createDrawerNavigator()时会第一时间触发reanimated的模块初始化逻辑- 当前使用的
react-native-reanimated@2.8.0和react-native@0.68.2的Chrome远程调试模式存在兼容缺陷:RN0.68的Chrome远程调试逻辑是把JS代码运行在桌面端Chrome的V8引擎中,所有Native模块调用默认走异步桥接,但reanimated 2.8.0初始化阶段存在同步Native方法调用逻辑,该逻辑在非调试模式(直接运行在移动端原生JS引擎)可以正常执行,在Chrome远程调试模式下会直接抛出同步调用不支持的错误 - 第一个报错抛出后会导致
AppScreens.tsx整个模块加载失败,模块导出的AppScreens变量变为undefined,最终触发第二个读取undefined属性的报错
可行修复方案
方案1:升级兼容版依赖(优先推荐)
将react-native-reanimated升级到2.9.1及以上的2.x稳定版本,该版本分支专门修复了RN0.68+版本下Chrome调试的同步调用兼容问题,升级后无需修改业务代码,重新安装依赖、重建原生依赖即可:
# 安装兼容版本的reanimated npm install react-native-reanimated@^2.17.0 # iOS端需要进入ios目录重新安装pod依赖 cd ios && pod install
注意不要直接升级到reanimated 3.x版本,3.x版本对RN0.68的兼容度较差,容易引发其他运行时问题
方案2:替换调试工具
如果不想改动现有依赖版本,可以放弃Chrome远程调试模式,改用Flipper内置调试器或者RN官方的React Native DevTools,这类调试工具直连移动端运行的JS引擎,不会触发远程调试的同步Native调用限制,可以正常调试抽屉导航相关功能。
方案3:临时规避(仅应急调试使用)
如果必须使用Chrome调试非导航类的业务逻辑,可以在开发环境下临时将Drawer Navigator替换为普通Stack Navigator,待相关业务逻辑调试完成后再切回Drawer导航,该方案操作成本较高,仅适合临时应急场景。
内容的提问来源于stack exchange,提问作者Gandalf
相关产品推荐
相关产品推荐

