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

Lerna Monorepo引入包出现React Hook调用错误求助

问题解决:Lerna Monorepo中React Hook调用错误

错误信息

react.development.js:210 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
   react.development.js:1619 Uncaught TypeError: Cannot read properties of null (reading 'useContext')
   at Object.useContext (react.development.js:1619:21)
   at useTheme (useThemeWithoutDefault.js:16:59)
   at useTheme (useTheme.js:14:77)
   at Box (createBox.js:37:72)
   at renderWithHooks (react-dom.development.js:15486:18)
   at updateForwardRef (react-dom.development.js:19240:20)
   at beginWork (react-dom.development.js:21670:16)
   at HTMLUnknownElement.callCallback (react-dom.development.js:4164:14)

相关代码

@dummy/login/lib/login.tsx

import * as React from 'react';
import { styled } from '@mui/material/styles';
import Box from '@mui/material/Box';
import Paper from '@mui/material/Paper';

const Item = styled(Paper)(({ theme }) => ({
backgroundColor: theme.palette.mode === 'dark' ? '#1A2027' : '#fff',
...theme.typography.body2,
padding: theme.spacing(1),
textAlign: 'center',
color: theme.palette.text.secondary,
}));

export default function Login() {
return (
<Box>
<p>I am inside FE code.</p>
</Box>
);
}

导入组件的应用代码

import Login from "@dummy/login";
import React from "react";
import Box from '@mui/material/Box';

const LoginComponent:any = () => {
return (
<Box>
<Login></Login>
</Box>
)
}
export default LoginComponent;

问题核心

错误提示第三条已明确原因:应用中存在多份React副本。@dummy/login包自身安装了React,主应用也有独立的React实例,导致MUI的styled组件调用useContext时找不到正确的React上下文,触发Hook调用错误。

解决方案

1. 配置Peer Dependencies + 共享根依赖

在@dummy/login的package.json中,将React、ReactDOM和MUI相关依赖移至peerDependencies,声明这些依赖由宿主应用提供,避免子包重复安装:

{
  "peerDependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "@mui/material": "^5.14.0",
    "@mui/material/styles": "^5.14.0"
  }
}

如果使用Lerna配合Yarn Workspaces,确保根目录package.json已声明工作区并安装共享依赖:

{
  "workspaces": ["packages/*"],
  "dependencies": {
    "react": "^18.2.0",
    "react-dom": "^18.2.0",
    "@mui/material": "^5.14.0"
  }
}

执行lerna bootstrap或yarn install重新安装依赖,此时所有子包会共享根目录的React实例。

2. 手动链接React实例

临时调试时,可在@dummy/login包目录下执行以下命令,强制子包使用主应用的React副本:

# 替换为你的主应用实际路径
npm link ../main-app/node_modules/react
npm link ../main-app/node_modules/react-dom

3. 清理重复依赖

删除所有包的node_modules、根目录的package-lock.json/yarn.lock,然后重新运行安装命令,彻底清除重复依赖:

# 清理所有子包的node_modules
lerna clean --yes
# 重新安装所有依赖
lerna bootstrap

验证

完成上述操作后,重新构建@dummy/login包,主应用导入组件后,Hook调用会关联到正确的React上下文,页面将正常显示"I am inside FE code."。

内容的提问来源于stack exchange,提问作者shaik Mohd Irfan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 04:50:20