在过去的几周里,我一直在尝试创建自己的组件库,除我无法使用钩子这一事实外,其他一切都进行得很顺利。每当我从库中导入使用钩子的组件时,我都会得到“只能在函数组件的主体内部调用钩子”。
https://reactjs.org/warnings/invalid-hook-call-warning.html
我希望这与React被复制有关,在我运行npm ls react
时看不到。
这是我的webpack.config.js
const path = require('path');
var nodeExternals = require('webpack-node-externals');
module.exports = {
entry: './src/index.js',
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
}
},
{
test: /\.scss$/,
sideEffects: true,
use: [
{ loader: 'style-loader' },
{ loader: 'css-loader' },
{ loader: 'sass-loader' },
],
},
{
test: /\.(png|gif|jpg|svg)$/,
use: {
loader: 'url-loader',
options: {
limit: 50000,
},
},
},
{
test: /\.(woff(2)?|ttf|eot|svg)(\?v=\d+\.\d+\.\d+)?$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
]
}
],
},
resolve: {
extensions: ['.scss', '.ttf', '.js', '.json', '.png', '.gif', '.jpg', '.svg'],
},
output: {
path: path.resolve(__dirname, 'dist/'),
publicPath: '',
filename: 'index.js',
libraryTarget: 'umd',
},
target: 'node',
externals: [ nodeExternals() ]
};
这是我的package-json
{
"name": "ui-components",
"version": "1.1.1",
"description": "componentes UI",
"main": "dist/index.js",
"scripts": {
"test": "jest",
"build": "webpack --mode production",
"storybook": "start-storybook -p 9001",
"docz:dev": "docz dev",
"docz:build": "docz build"
},
"repository": {
"type": "git",
"url": "..."
},
"keywords": [
"react",
"shared",
"components",
"botbit"
],
"author": "Uriel Chami",
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.2.2",
"@babel/preset-env": "^7.2.3",
"@babel/preset-react": "^7.0.0",
"@storybook/addon-actions": "^5.0.0",
"@storybook/addon-storyshots": "^5.1.10",
"@storybook/react": "^5.0.0",
"@tulipjs/eslint-config": "^1.1.1",
"babel-loader": "^8.0.1",
"babel-plugin-macros": "^2.6.1",
"css-loader": "^1.0.0",
"docz": "^1.2.0",
"docz-theme-default": "^1.2.0",
"file-loader": "^4.1.0",
"jest": "^24.8.0",
"node-sass": "^4.9.3",
"react": "^16.9.0",
"react-dom": "^16.9.0",
"react-router-dom": "^5.0.1",
"react-test-renderer": "^16.8.6",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"url-loader": "^1.1.2",
"webpack": "^4.28.3",
"webpack-cli": "^3.2.0",
"webpack-node-externals": "^1.7.2"
},
"peerDependencies": {
"react": "16.9.0",
"react-dom": "16.9.0"
},
"dependencies": {
"mdbreact": "..."
}
}
我正在使用npm link
来测试库的功能,但是我也可以将其部署到GitHub上并npm update
进行部署。
我已经在node_modules / react-dom / index.js(使用我的库的应用程序中)中添加了window.React1 = require('react');
。
还有
require('react-dom');
window.React2 = require('react');
console.log(window.React1);
console.log(window.React1 === window.React2);
在我的App.js中(在使用我的库的应用中)。
它抛出true
。我慢慢变得一无所知。有什么想法吗?
编辑:
我尝试使用Hooks的代码是:
import React, {useEffect} from 'react';
export const Test = () => {
useEffect(()=>{
console.log("component did mount");
} , [])
return(<div>Hola!</div>);
}
编辑2
当我构建yarn webpack --mode development
时,它抛出'require not defined'(未定义需求)。
如果有人想开玩笑,这里是我完整代码的GitHub存储库:https://github.com/uchami/hooks-not-working
编辑3
我以yarn add git+ssh:repository
的形式添加了组件库(ui-components)。
我导入库的应用程序只是一个普通的create-react-app。
我只是使用Test
实现import {Test} from 'ui-components'
组件(使用Hooks的组件),就象<Test></Test>
一样使用它。
ui-components
项目的编译只是控制台上的yarn build
。在后台执行的操作是调用yarn webpack --mode production
。如果您致电yarn webpack --mode development
,将会看到额外的详细错误输出。
答案 0 :(得分:2)
让我们根据link排除所有可能性。
您的React和React DOM版本可能不匹配。
您可能正在违反挂钩规则。
您可能在同一应用程序中拥有多个React副本。
1。)如果不确定,请尝试在您的应用中以最新版本重新安装react
和react-dom
,以使它们100%匹配(或查看您的package-lock.json
/ yarn锁)。
npm i react@latest react-dom@latest
2。)您在测试组件中的useEffect
钩看起来不错。
3。)如果必须选择,这将是我的主要猜测。
您说过,您npm link
在本地测试库中。 npm link
将为应用程序项目的“ node_modules”内的完整库工作目录(包括“ node_modules”)添加符号链接。您已经在library中将react
作为devDependencies以及在您的应用程序项目中作为依赖项安装了(顺便说一句,您可以从库中删除react-dom
,仅将组件作为API提供)。您的应用程序项目,它将选择在库中还是在应用程序中做出反应-相对于导入模块而言,包含在最近的node_modules
文件夹中。
在同一hook warning page上提到了一个修复程序:
假设myapp和mylib是同级文件夹,一种可能的解决方法是从mylib运行npm链接../myapp/node_modules/react。这应该使库使用应用程序的React副本。
替代方法:告诉Webpack始终只解析一个反应包(您的应用程序node_modules中的一个)。 webpack.config.js:
resolve: {
...
alias: {
// Needed when you are link your library via `npm link` to the app.
// react-dom should be only installed in app.
react: path.resolve("./node_modules/react")
}
}
当您运行的Web应用程序被错误的Webpack配置捆绑在一起时,可能会发生这种情况,在该应用程序中,要求调用不会被丢弃,并由实际的代码模块代替。
如果您的应用程序项目基于create-react-app,则只需将您的库导入应用程序中并执行start或build。如果您为应用程序使用自定义Webpack配置(例如,退出cra设置),请使用target:web
(或忽略目标)运行构建,并忽略externals: [ nodeExternals() ]
-看一下{{3} }。
答案 1 :(得分:1)
仅仅是您要在运行与钩子不兼容的旧版React的React应用中使用您的库吗?
我刚刚创建了一个新的create-react-app,将您的存储库添加为yarn add https://github.com/uchami/hooks-not-working
的依赖项,并且毫无疑问将Test组件添加到默认的App.js
。
回滚我应用的React版本后,我才得到一个错误。
答案 2 :(得分:1)
这可能也有帮助: React hooks duplicate react package
我遇到了同样的问题,但更糟糕的是,我必须使用自己的库来管理多个应用程序。
提出的解决方案可以解决所有“多个反应库”错误
答案 3 :(得分:0)
您是否尝试过将目标从node
更改为web
?这可能会导致一些问题。
也不知道计划使用库的所有详细信息,但是当您在已经具有可处理构建步骤的环境中使用库时,babel ./src --out-dir ./core --copy-files
这样的简单操作可能会很有用捆绑。
我要添加评论,但嗯。