升级React Native从0.71.12到0.73.0后出现useContext为null的钩子错误求助
升级React Native 0.71.12到0.73.0后出现useContext null及无效钩子调用问题排查
我负责维护一个monorepo架构的React Native应用,最近从0.71.12版本升级到0.73.0,全程遵循React Native Upgrade Helper的指引操作。应用编译环节正常,但启动Metro并执行yarn android后,出现两个关键运行时错误:
- Invalid hook call warning
- Cannot read property 'useContext' of null
我已经尝试过以下排查步骤:
- 确认monorepo中react、react-native、react-dom无版本冲突
- 在根package.json中添加resolutions配置强制统一依赖版本
- 全面检查组件代码,确保完全遵守React钩子规则(无条件/循环内调用钩子、自定义钩子命名规范等)
- 验证Android SDK的API级别、NDK版本等配置符合RN 0.73.0的要求
- 对照Upgrade Helper更新了所有指定的配置文件和依赖声明
回退到0.71.12版本后所有功能完全正常,说明问题完全由本次版本升级引发。以下是可能的原因及对应的解决方案:
可能的原因及解决方向
1. Monorepo依赖hoisting异常
RN 0.73对依赖的hoisting策略要求更严格,即便根目录设置了resolutions,部分子包仍可能单独安装一份react/react-native,导致运行时存在多个React实例,直接触发钩子调用错误。
- 排查&修复:
- 执行
yarn why react和yarn why react-native,查看输出中是否存在多个版本或重复的依赖实例 - 在根package.json的
workspaces配置中添加反向nohoist规则,确保核心依赖在所有子包中共享根目录版本:"workspaces": { "packages": ["packages/*"], "nohoist": [ "**/react", "**/react-dom", "**/react-native", "**/react-native/**" ] } - 删除所有node_modules目录和lock文件(yarn.lock),重新执行
yarn install
- 执行
2. Metro配置未适配Monorepo及RN 0.73版本
RN 0.73升级了Metro版本,默认配置可能无法正确解析monorepo的依赖路径,导致重复加载React模块。
- 排查&修复:
- 修改项目根目录的metro.config.js,添加monorepo路径解析支持:
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); const path = require('path'); const customConfig = { resolver: { nodeModulesPaths: [ path.resolve(__dirname, 'node_modules'), // 根据你的子包路径调整,比如主应用在packages/app下 path.resolve(__dirname, 'packages/app/node_modules'), ], disableHierarchicalLookup: true, }, }; module.exports = mergeConfig(getDefaultConfig(__dirname), customConfig); - 执行
npx metro-cache clean清除Metro缓存后重新启动服务
- 修改项目根目录的metro.config.js,添加monorepo路径解析支持:
3. 第三方依赖兼容性问题
RN 0.73默认依赖React 18.2,部分第三方库(尤其是自定义hooks、状态管理库)可能未适配React 18的特性,导致钩子调用异常。
- 排查&修复:
- 检查package.json中所有依赖的版本,查看是否有库明确标注不支持React 18或RN 0.73
- 升级所有第三方依赖到最新兼容版本,重点关注直接使用React钩子的库
- 临时禁用非核心第三方库,逐一排查定位是否由某个特定库引发问题
4. Android端缓存残留
即使编译正常,旧版本的构建缓存可能和新RN版本冲突,导致运行时错误。
- 排查&修复:
- 进入android目录执行
./gradlew clean清除构建缓存 - 卸载模拟器/真机上的应用后重新安装
- 进入android目录执行
内容的提问来源于stack exchange,提问作者Sam Magdaleno
相关产品推荐
相关产品推荐

