You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将Expo应用迁移至PNPM Monorepo后出现Invalid hook call错误求助

解决PNPM Monorepo中Expo应用的Invalid Hook Call错误

这个错误的核心原因是项目中存在多个React实例,即使你已经在Expo应用本地安装了React,PNPM的链接机制和Metro的模块解析规则可能还是导致了重复加载。以下是针对性的修复步骤:

1. 强制Monorepo全局使用统一的React版本

在Monorepo根目录的package.json中添加pnpm.overrides配置,强制所有子包使用与Expo兼容的React版本:

{
  "pnpm": {
    "overrides": {
      "react": "~18.2.0", // 匹配你的Expo版本对应的React版本
      "react-dom": "~18.2.0",
      "react-native": "0.72.6" // 必须与Expo依赖的React Native版本完全一致
    }
  }
}

执行pnpm install重新安装所有依赖,确保全局依赖版本统一。

2. 修正Metro配置,避免重复解析React

修改Expo项目根目录的metro.config.js,添加关键配置项阻止层级查找,并确保自定义库的解析路径正确:

const { getDefaultConfig } = require('expo/metro-config');
const path = require('path');

const projectRoot = __dirname;
const monorepoRoot = path.resolve(projectRoot, '../..');

const config = getDefaultConfig(projectRoot);

// 优先使用项目本地和根目录的node_modules
config.resolver.nodeModulesPaths = [
  path.join(projectRoot, 'node_modules'),
  path.join(monorepoRoot, 'node_modules'),
];
config.watchFolders = [monorepoRoot];

// 禁用层级依赖查找,避免加载自定义库中的重复React
config.resolver.disableHierarchicalLookup = true;

// 映射自定义本地库到实际路径(替换为你的库路径)
const extraNodeModules = {
  '@your-org/ui': path.resolve(monorepoRoot, 'packages/ui'),
  '@your-org/utils': path.resolve(monorepoRoot, 'packages/utils'),
};
config.resolver.extraNodeModules = extraNodeModules;

module.exports = config;

3. 调整自定义库的依赖配置

所有共享库的package.json中,必须将React、React Native设置为peerDependencies,避免库自身安装独立的React实例:

{
  "peerDependencies": {
    "react": "^18.2.0",
    "react-native": "^0.72.0"
  },
  "devDependencies": {
    "react": "^18.2.0",
    "react-native": "^0.72.0"
  }
}

4. 彻底清理缓存

执行以下命令清理所有缓存,确保新配置生效:

# 清理Expo和Metro缓存
npx expo start --clear

# 清理PNPM缓存并重新安装
pnpm store prune
rm -rf node_modules
rm -rf ../../node_modules
pnpm install

5. 验证React实例唯一性

在Expo应用的App.tsx和自定义库的组件中分别添加日志,确认使用的是同一个React实例:

// Expo App.tsx
import React from 'react';
console.log('Expo React Instance:', React);
console.log('Expo React Version:', React.version);

// 自定义库组件
import React from 'react';
console.log('Library React Instance:', React);

如果两个日志输出的实例引用一致,说明问题已解决;若不一致,回到步骤2检查Metro配置是否正确映射了库路径。

内容的提问来源于stack exchange,提问作者Rémi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 06:03:19