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

子项目依赖管理:解决React版本重复引发的Hook调用错误

React Hooks无效调用问题:多份React去重后仍报错

我正在开发一个React库模板,主项目导出基础React Hooks,内部包含的example子项目通过package.json中的"@local/lib": "file:.."引入该库。两者原本均依赖React 18.3.1,但使用Hooks时出现如下警告:

index.js:163 Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.

推测是多份React导致该问题,我将example项目的React依赖修改为"react": "file:../node_modules/react"和"react-dom": "file:../node_modules/react-dom",删除node_modules后重装,执行npm ls react显示已去重:

example@0.1.0 /home/ptolemy/webpages/npm/react-mount-effects/example
├─┬ @ptolemy2002/react-mount-effects@0.1.0 -> ./..
│ ├─┬ react-dom@18.3.1
│ │ └── react@18.3.1 deduped
│ └── react@18.3.1
├─┬ react-dom@18.3.1 -> ./../node_modules/react-dom
│ └── react@18.3.1 deduped
├─┬ react-error-boundary@4.0.13
│ └── react@18.3.1 deduped -> ./../node_modules/react
├─┬ react-router-bootstrap@0.26.3
│ └── react@18.3.1 deduped -> ./../node_modules/react
├─┬ react-router-dom@6.25.1
│ ├─┬ react-router@6.25.1
│ │ └── react@18.3.1 deduped -> ./../node_modules/react
│ └── react@18.3.1 deduped -> ./../node_modules/react
├─┬ react-scripts@5.0.1
│ └── react@18.3.1 deduped -> ./../node_modules/react
└── react@18.3.1 -> ./../node_modules/react

但错误仍未消失,推测仍存在多份React。项目完整源码可查看GitHub仓库Ptolemy2002/react-mount-effects。


解决方案

1. 主项目配置peerDependencies

React库开发的标准做法是将react和react-dom声明为peerDependencies,而非dependencies,这样库会复用宿主项目(example)的React实例,避免重复安装。

修改主项目的package.json:

{
  "peerDependencies": {
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  },
  // 本地开发需保留devDependencies
  "devDependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1"
  }
}

2. 重置example项目的依赖配置

将example项目中指向本地的react依赖改回正常版本声明,主项目已通过peerDependencies复用example的React:

{
  "dependencies": {
    "react": "^18.3.1",
    "react-dom": "^18.3.1",
    "@local/lib": "file:.."
  }
}

3. 彻底清理并重装依赖

  • 删除主项目和example项目的node_modules文件夹
  • 删除主项目和example项目的package-lock.json(或yarn.lock)
  • 主项目执行npm install,再到example项目执行npm install

4. 强制Webpack解析同一React实例(针对Create React App)

如果使用Create React App,可通过craco修改Webpack配置,强制所有模块指向同一个React:

安装craco:

npm install @craco/craco --save-dev

在example项目根目录创建craco.config.js:

const path = require('path');

module.exports = {
  webpack: {
    alias: {
      'react': path.resolve(__dirname, '../node_modules/react'),
      'react-dom': path.resolve(__dirname, '../node_modules/react-dom')
    }
  }
};

修改example项目的启动脚本:

{
  "scripts": {
    "start": "craco start",
    "build": "craco build",
    "test": "craco test"
  }
}

5. 验证实例唯一性

执行命令检查React安装路径,确认所有依赖指向同一位置:

cd example
npm list react --depth=0

或在浏览器开发者工具中执行:

// 检查是否为同一React实例,返回true则正常
console.log(require('react') === require('../node_modules/react'));

内容的提问来源于stack exchange,提问作者Ptolemy2002

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 20:27:06