本地启动React应用报Invalid hook call错误求助
解决React本地启动"Invalid hook call"错误
问题现象
本地执行npm start后页面空白,控制台抛出错误:
Uncaught Error: 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 `url` for tips about how to debug and fix this problem. React 2 useTheme useTheme.js:4 ThemeProvider ThemeProvider.js:34 React 17 tsx index.tsx:7 factory react refresh:6 Webpack 3 __webpack_require__ <anonymous> <anonymous> react.development.js:1465 React 2 useTheme useTheme.js:4 ThemeProvider ThemeProvider.js:34 React 17 tsx index.tsx:7 factory react refresh:6 Webpack 3
生产环境稳定运行2年无改动,结合npm ls react输出,确认项目中存在多版本React:
+-- @material-ui/core@4.12.3 | +-- @material-ui/styles@4.11.4 | | `-- react@16.14.0 deduped | +-- @material-ui/system@4.12.1 | | `-- react@16.14.0 deduped | +-- @material-ui/utils@4.11.2 | | `-- react@16.14.0 deduped | +-- react-dom@16.14.0 | | `-- react@16.14.0 deduped | +-- react-transition-group@4.4.2 | | `-- react@16.14.0 deduped | `-- react@16.14.0 +-- @material-ui/icons@4.11.2 | `-- react@16.14.0 deduped +-- @material-ui/lab@4.0.0-alpha.60 | `-- react@16.14.0 deduped +-- @testing-library/react@12.1.3 | `-- react@16.14.0 deduped +-- material-table@1.69.3 | +-- @material-ui/pickers@3.2.2 | | +-- react@16.14.0 deduped | | `-- rifm@0.7.0 | | `-- react@16.14.0 deduped | +-- react-beautiful-dnd@13.0.0 | | +-- react-redux@7.2.6 | | | `-- react@16.14.0 deduped | | +-- react@16.14.0 deduped | | `-- use-memo-one@1.1.2 | | `-- react@16.14.0 deduped | +-- react-double-scrollbar@0.0.15 | | `-- react@16.14.0 deduped | `-- react@16.14.0 deduped +-- react-dom@17.0.2 | `-- react@17.0.2 deduped +-- react-router-dom@6.2.1 | +-- react-router@6.2.1 | | `-- react@16.14.0 deduped | `-- react@17.0.2 deduped +-- react-scripts@5.0.0 | `-- react@16.14.0 deduped +-- react@17.0.2 `-- swr@1.2.2 `-- react@16.14.0 deduped
问题原因
项目根依赖指定React 17.0.2,但多个第三方依赖(如@material-ui/core、react-scripts)依赖React 16.14.0,导致本地开发环境加载了两个不同版本的React实例。Hook依赖React内部的全局状态,多版本实例会导致状态无法共享,触发"Invalid hook call"错误。生产环境构建时会自动合并重复依赖,因此无此问题。
修复步骤
1. 配置依赖强制统一版本
在package.json中添加resolutions字段,强制所有子依赖使用项目指定的React版本,并添加预安装脚本确保生效:
{ "name": "my-app-react-pwa", "version": "0.1.0", "private": true, "homepage": ".", "resolutions": { "react": "^17.0.2", "react-dom": "^17.0.2" }, "dependencies": { "@azure/msal-browser": "^2.22.0", "@material-ui/core": "^4.12.3", "@material-ui/icons": "^4.11.2", "@material-ui/lab": "^4.0.0-alpha.60", "@testing-library/jest-dom": "^5.16.2", "@testing-library/react": "^12.1.3", "@testing-library/user-event": "^13.5.0", "@types/jest": "^27.4.0", "@types/node": "^17.0.19", "@types/react": "^17.0.39", "@types/react-dom": "^17.0.11", "date-fns": "^2.28.0", "material-table": "^1.69.3", "react": "^17.0.2", "react-dom": "^17.0.2", "react-router-dom": "^6.2.1", "react-scripts": "^5.0.0", "store2": "^2.13.1", "swr": "^1.2.2", "typescript": "^4.5.5" }, "scripts": { "preinstall": "npm-force-resolutions", "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test" }, "eslintConfig": { "extends": "react-app" }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] } }
2. 安装依赖强制工具
执行命令安装npm-force-resolutions(用于npm环境下强制应用resolutions配置):
npm install -g npm-force-resolutions
3. 清理并重新安装依赖
删除旧的依赖文件和锁文件,重新安装依赖:
rm -rf node_modules package-lock.json npm install
4. 验证依赖版本
再次运行npm ls react,确认所有React实例都指向17.0.2,无16.14.0版本存在。
5. 重启开发服务器
关闭当前运行的npm start进程,重新启动:
npm start
额外排查点
如果问题仍未解决,检查:
- 确认
AzureAdAuthenticator组件内部是否存在违反Hook规则的调用(如在条件判断、循环、嵌套函数中使用Hook) - 检查
theme.ts文件中是否正确创建Material UI主题,无错误调用Hook的情况
内容的提问来源于stack exchange,提问作者PalBo
相关产品推荐
相关产品推荐

