TypeScript函数组件内用React useState仍报Invalid hook call错误
React组件库Hook调用错误排查问题
我正在开发一个React自定义组件库,为Button组件的hover功能实现useState时,create-react-app生成的项目浏览器控制台出现无效hook调用错误。已经排查了一段时间,虽然严格按照规则在函数组件顶层定义了hook,但错误依旧。
浏览器控制台错误
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:
- React与渲染器(如React DOM)版本不匹配
- 违反了Hooks的使用规则
- 应用中存在多个React副本
已尝试的解决方法
const [hover, setHover] = useState(false);确实定义在函数组件顶层- 在组件库和项目中移除并重新安装v18.3.0版本的react、react-dom及其类型
@types/react、@types/react-dom - 在项目中执行
npm ls react发现来自组件库的多余react,执行npm prune清理 - 在Firefox和Edge浏览器测试
- 提取组件库中的最小Button组件,重新搭建最简组件库和测试项目,发现仅添加
useState时才会报错 - 移除CRA项目中的react依赖,仅使用组件库中的react,执行
npm prune并删除package-lock.json,问题仍存在
组件库代码
Button组件代码(./jaghu/src/components/Button/Button.tsx)
import React, { useState } from "react"; export interface IButtonProps extends React.DetailedHTMLProps< React.ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement > { backgroundColor?: string; color?: string; width?: string; height?: string; } export const Button: React.FunctionComponent<IButtonProps> = (props) => { const [hover, setHover] = useState(false); const MouseOver = () => setHover(true); const MouseOut = () => setHover(false); const { backgroundColor, width, height } = props; let _style: React.CSSProperties = { width: width ? width : "200px", height: height ? height : "100px", backgroundColor: backgroundColor ? backgroundColor : "skyblue", color: hover ? "black" : "red", }; /** Override Defaults CSS data using the values in Props CSS */ if (backgroundColor) _style.backgroundColor = backgroundColor; if (width) _style.width = width; if (height) _style.height = height; return ( <button style={_style} onMouseEnter={MouseOver} onMouseLeave={MouseOut} > Hello BuTToNo </button> ); };
组件库package.json(./jaghu/package.json)
{ "name": "jaghu", "version": "1.0.0", "license": "MIT", "devDependencies": { "@types/node": "^22.0.0", "@types/react": "18.3.0", "@types/react-dom": "18.3.0", "@types/react-helmet": "^6.1.11", "prettier": "^3.3.3", "react": "18.3.0", "react-dom": "18.3.0", "react-helmet": "^6.1.0", "typescript": "^5.5.4" }, "scripts": { "build": "rm -rf dist/ && prettier --write src/ && yarn run build:esm && yarn run build:cjs", "build:esm": "tsc", "build:cjs": "tsc --module CommonJS --outDir dist/cjs" }, "main": "dist/cjs/index.js", "module": "dist/esm/index.js", "files": [ "dist" ], "dependencies": {} }
测试项目代码
App组件代码(./app/src/App.js)
import {Button} from 'jaghu'; function App() { return ( <div className="App"> <Button></Button> </div> ); } export default App;
测试项目package.json(./app/package.json)
{ "name": "app", "version": "0.1.0", "private": true, "dependencies": { "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^13.0.0", "@testing-library/user-event": "^13.2.1", "react-dom": "18.3.0", "react-scripts": "5.0.1", "web-vitals": "^2.1.0" }, "scripts": { "start": "react-scripts start", "build": "react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": [ "react-app", "react-app/jest" ] }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "devDependencies": { "jaghu": "../jaghu" } }
内容的提问来源于stack exchange,提问作者Remix Protocol
相关产品推荐
相关产品推荐

