本地安装私有React TS npm包时触发useEffect调度器为空错误
本地安装私有React TypeScript npm包时出现Invalid Hook Call错误的解决方法
我正在构建一个私有npm包,用于在多个React TypeScript项目中复用组件和函数。当通过本地路径安装该包时,会触发以下错误:Warning: Invalid hook call. [...]can't access property "useEffect", dispatcher is null
项目和npm包都使用React 18.2.0,且确认没有违反Hook规则,示例代码只是简单的useEffect:
npm包代码:
import * as React from "react"; export interface ITestProps {} const Test: React.FunctionComponent<ITestProps> = (props) => { React.useEffect(() => { console.log("React useEffect hook called..."); }, []); return <div>Test is working.</div>; }; export default Test;
React示例项目代码:
import Test from "@xyz/my-package"; function App() { return ( <div className="App"> <Test /> </div> ); } export default App;
注:上述错误仅在本地安装npm包时出现,将包
npm publish后从npm服务器安装则一切正常。
经排查确认问题源于存在多个React副本,npm ls react也显示确实加载了多个React实例,但添加React到peerDependencies后问题仍未解决。
解决方法
1. 修正peerDependencies配置
在私有包的package.json中,确保React和ReactDOM只存在于peerDependencies中,不要放在dependencies或devDependencies内:
{ "peerDependencies": { "react": "^18.2.0", "react-dom": "^18.2.0" }, "devDependencies": { // 仅保留开发依赖,如@types/react、typescript等,不要包含react本体 } }
2. 使用npm link共享React实例
本地安装时,直接通过路径安装会让私有包单独安装一份React,通过link方式可以让它复用主项目的React:
- 方式一:在主项目中直接关联私有包
npm link ../path-to-your-private-package - 方式二:先在私有包目录执行
npm link,再在主项目执行npm link @xyz/my-package
3. 强制统一React版本
如果link方式无效,可以在主项目的package.json中添加resolutions强制所有模块使用同一份React:
{ "resolutions": { "react": "18.2.0", "react-dom": "18.2.0" } }
之后重新安装依赖:
# npm用户需先安装npm-force-resolutions npx npm-force-resolutions && npm install # yarn用户直接执行 yarn install
4. 配置webpack别名(主项目用webpack时)
在主项目的webpack配置中添加resolve.alias,强制所有模块引用主项目的React:
module.exports = { resolve: { alias: { 'react': path.resolve(__dirname, 'node_modules/react'), 'react-dom': path.resolve(__dirname, 'node_modules/react-dom') } } };
5. 清理依赖缓存
缓存可能导致依赖重复,执行以下命令清理后重装:
# 清理npm缓存 npm cache clean --force # 删除主项目和私有包的node_modules及锁文件 rm -rf node_modules package-lock.json rm -rf ../path-to-your-private-package/node_modules package-lock.json # 重新安装依赖 npm install
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

