无效的钩子调用来自私有存储库的组件



我已经创建了一个私有的(即将)组件的repo。现在,这里有一个按钮和一个文本框。这两者都可以独立工作(使用CRA创建)。这是一个简单的TextField:

import React, { useState } from "react";
import classnames from "classnames";
import { Icon, IconType } from "../Icon";
interface Props {
id?: string,
name?: string,
type?: "text" | "password" | "email" | "number",
label?: string,
error?: string,
placeholder?: string,
className?: string,
iconType?: IconType,
value?: string,
onChange: (e: React.FormEvent<HTMLInputElement>) => void,
enabledShowHide?: boolean,
autoComplete?: "email" | "current-password",
}
const TextField = ({ id, name, type = "text", label, error, placeholder, className, iconType, value, onChange, enabledShowHide, autoComplete }: Props) => {
const [showPassword, setShowPassword] = useState<boolean>(false);
const toggleShowPassword = () => {
setShowPassword(!showPassword);
};
const renderIcon = () => {
if (enabledShowHide && type === "password") {
return (
<button type="button" onClick={toggleShowPassword} className="px-2 py-2 focus:outline-none transition text-primary-500 focus-within:text-primary-800">
{showPassword
? <Icon className="h-5 w-5" type="eyeHide" />
: <Icon className="h-5 w-5" type="eyeShow" />}
</button>
);
}
if (error) {
return <Icon className="text-red-500 pointer-events-none" type="error" aria-hidden="true" />;
}
return iconType
? <Icon className="h-5 w-5 text-primary-500 pointer-events-none" type={iconType} />
: false;
};
const getPasswordDisplay = (): string => (showPassword ? "text" : "password");
return (
<div className="mb-4">
<label htmlFor={id} className="block text-sm font-medium text-gray-700 pl-2">
{label}
</label>
<div className="mt-1 relative shadow-sm">
<input
type={type === "password" && enabledShowHide ? getPasswordDisplay() : type}
autoComplete={autoComplete}
name={name}
id={id}
className={classnames(
"block w-full pr-10 focus:outline-none sm:text-sm border-0 border-b placeholder-gray-400 transition",
"ring-0 focus:ring-0 focus:ring-1 focus:ring-offset-0 ring-opacity-50",
error
? "border-red-500 text-red-900 placeholder-red-300 focus:ring-b-red-500 focus:border-red-500"
: "border-primary-500 focus:border-primary-500 focus:ring-gray-300",
className,
)}
placeholder={placeholder}
aria-invalid={!!error}
value={value}
onChange={onChange}
/>
<div className="absolute inset-y-0 right-0 flex items-center pr-3">
{renderIcon()}
</div>
</div>
{error && (
<p className="mt-2 text-xs text-red-600">
{error}
</p>
)}
</div>
);
};
export { TextField };

当我尝试在不同的项目中使用这个私有NPM包时(同样使用CRA),我得到"Hooks只能在函数组件的内部调用";useState.

使用如下组件:

<TextField onChange={() => {}} />

我在两个项目中使用typescript。NPM在package.json

{
"name": "react-package",
"version": "0.1.0",
"private": true,
"main": "./lib/cjs/index.js",
"module": "./lib/esm/index.js",
"types": "./lib/esm/index.d.ts",
"peerDependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"resolutions": {
"@types/react": "^17.0.19",
"@types/react-dom": "^17.0.9"
},
"dependencies": {
"@babel/core": "7.12.3",
"@fortawesome/fontawesome-svg-core": "^1.2.35",
"@fortawesome/free-solid-svg-icons": "^5.15.3",
"@fortawesome/react-fontawesome": "^0.1.14",
"@headlessui/react": "1.3.0",
"@pmmmwh/react-refresh-webpack-plugin": "0.4.3",
"@svgr/webpack": "5.5.0",
"@tailwindcss/forms": "^0.3.2",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"@types/jest": "^26.0.15",
"@types/node": "^12.0.0",
"@typescript-eslint/eslint-plugin": "^4.26.0",
"@typescript-eslint/parser": "^4.5.0",
"babel-eslint": "^10.1.0",
"babel-jest": "^26.6.0",
"babel-loader": "8.1.0",
"babel-plugin-named-asset-import": "^0.3.7",
"babel-preset-react-app": "^10.0.0",
"bfj": "^7.0.2",
"camelcase": "^6.1.0",
"case-sensitive-paths-webpack-plugin": "2.3.0",
"classnames": "^2.3.1",
"css-loader": "4.3.0",
"dotenv": "8.2.0",
"dotenv-expand": "5.1.0",
"eslint": "^7.11.0",
"eslint-plugin-flowtype": "^5.2.0",
"eslint-plugin-import": "2.22.0",
"eslint-plugin-jest": "^24.1.0",
"eslint-plugin-jsx-a11y": "6.3.1",
"eslint-plugin-react": "7.20.3",
"eslint-plugin-react-hooks": "4.0.8",
"eslint-plugin-testing-library": "^3.9.2",
"eslint-webpack-plugin": "^2.5.2",
"file-loader": "6.1.1",
"fs-extra": "^9.0.1",
"history": "4.10.1",
"html-webpack-plugin": "4.5.0",
"identity-obj-proxy": "3.0.0",
"jest": "26.6.0",
"jest-circus": "26.6.0",
"jest-resolve": "26.6.0",
"jest-watch-typeahead": "0.6.1",
"mini-css-extract-plugin": "0.11.3",
"optimize-css-assets-webpack-plugin": "5.0.4",
"pnp-webpack-plugin": "1.6.4",
"postcss-flexbugs-fixes": "4.2.1",
"postcss-loader": "3.0.0",
"postcss-normalize": "8.0.1",
"postcss-preset-env": "6.7.0",
"postcss-safe-parser": "5.0.2",
"prompts": "2.4.0",
"react-app-polyfill": "^2.0.0",
"react-dev-utils": "^11.0.3",
"react-refresh": "^0.8.3",
"react-router": "^5.2.0",
"react-router-dom": "5.2.0",
"resolve": "1.18.1",
"resolve-url-loader": "^3.1.2",
"sass-loader": "^10.0.5",
"semver": "7.3.2",
"store": "^2.0.12",
"style-loader": "1.3.0",
"terser-webpack-plugin": "4.2.3",
"ts-pnp": "1.2.0",
"typescript": "^4.1.2",
"url-loader": "4.1.1",
"web-vitals": "^1.0.1",
"webpack": "4.44.2",
"webpack-dev-server": "3.11.1",
"webpack-manifest-plugin": "2.2.0",
"workbox-webpack-plugin": "5.1.4"
},
"devDependencies": {
"@types/react": "^17.0.19",
"@types/react-dom": "^17.0.9",
"@types/react-router-dom": "^5.1.7",
"autoprefixer": "9",
"eslint-config-airbnb-typescript": "^12.3.1",
"postcss": "7",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"tailwindcss": "npm:@tailwindcss/postcss7-compat"
},
"scripts": {
"build": "yarn build:esm && yarn build:cjs",
"build:esm": "tsc",
"build:cjs": "tsc --module commonjs --outDir lib/cjs",
"build:css": "tailwind build -i src/Styles/index.css -o src/build.css",
"start": "node scripts/start.js",
"test": "node scripts/test.js"
},
"eslintConfig": {
"extends": [
"airbnb"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"babel": {
"presets": [
"react-app"
]
}
}

我通过将示例放在包的根目录中并通过"react-package": "link:..",

好了,我算出来了。

我的组件库安装了reactreact-dom。事件,尽管这些都在package.json的peerDependencies部分。

删除它们(也从peerDependencies中删除了它们)并重新添加到peerDependencies中解决了这个问题。

另外,我的一个组件使用useLocation,所以我还必须将其移动到peerDependencies部分以使其工作。

对不起,如果这对一些人来说很清楚,但我希望这能帮助别人:-)由于

最新更新