首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >不能使用钩子与我的反应组件库。不变冲突:无效钩子调用

不能使用钩子与我的反应组件库。不变冲突:无效钩子调用
EN

Stack Overflow用户
提问于 2019-08-12 02:57:49
回答 4查看 8.8K关注 0票数 12

在过去的几周里,我一直在尝试创建自己的组件库( Component ),一切都进展顺利,除了我无法让钩子工作的事实。每当我从库中导入一个使用钩子的组件时,我就会得到“钩子只能在函数组件的主体内调用”。

https://reactjs.org/warnings/invalid-hook-call-warning.html

我想这是因为我在运行npm ls react时没有看到的反应被复制。

这是我的webpack.config.js

代码语言:javascript
复制
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() ]
};

这是我的包裹-json

代码语言:javascript
复制
{
  "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_ added /react/index.js中添加了window.React1 = require('react'); (在使用我的库的应用程序中)。和

代码语言:javascript
复制
  require('react-dom');
  window.React2 = require('react');
  console.log(window.React1);
  console.log(window.React1 === window.React2);

在我的App.js中(在使用我的库的应用程序中)。

它抛出了true。我正慢慢变得不知所措。有什么想法吗?

编辑:

我试图使用钩子的代码是:

代码语言:javascript
复制
import React, {useEffect} from 'react';

export const Test = () => {
    useEffect(()=>{
        console.log("component did mount");
    } , [])
    return(<div>Hola!</div>);
}

编辑2

当我构建yarn webpack --mode development时,它会抛出'require‘不定义’‘。

这是一个GitHub回购,如果有人想玩的话,我的完整代码:https://github.com/uchami/hooks-not-working

编辑3

我将组件库(ui-components)添加为so yarn add git+ssh:repository。我导入库的应用程序只是一个简单的创建-反应-应用程序。

我只是使用import {Test} from 'ui-components'实现了import {Test} from 'ui-components'组件(也就是使用钩子的组件),我使用它就像使用<Test></Test>一样。

ui-components项目的编译只是控制台上的yarn build。在这个背景下,我们正在做的是调用yarn webpack --mode production。如果调用yarn webpack --mode development,您将看到额外的详细错误输出。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2019-08-17 16:28:37

“钩子只能在函数组件的主体内调用。”

让我们根据反应文档排除所有的可能性

  1. 您可能有与React和React不匹配的版本。
  2. 你可能破坏了钩子规则
  3. 您可能有多个副本的反应在同一应用程序。

1.)如果不确定,请尝试在应用程序的最新版本中重新安装reactreact-dom,以便它们100%匹配(或者查看您的package-lock.json /纱线锁):

代码语言:javascript
复制
npm i react@latest react-dom@latest

2.)useEffect钩子在Test中的使用看起来很好-- Test是一个函数组件,而useEffect是在顶层调用的。

3.)这将是我对手头的错误的主要猜测。

您正在使用npm link链接库以进行本地测试。npm link将在app项目的node_modules中为完整的库工作目录(包括node_modules)添加一个符号链接。react 已安装在库中既是devDependencies,也是应用程序项目中的dependencies

现在,当Webpack捆绑应用程序项目时,它将从库或应用程序中选择react --无论哪一个包含在相对于导入模块的最近的node_modules文件夹中。

解决方案

无效钩子呼叫警告页面中提到了一个修复:

假设myappmylib是同级文件夹,一个可能的解决方法是从mylib运行npm link ../myapp/node_modules/react。这应该使库使用应用程序的React副本。

另一种选择:告诉Webpack总是决心要一个单一的react包--你的应用程序node_modules中的一个(信用归于这些 two 问题)。webpack.config.js

代码语言:javascript
复制
resolve: {
  ...
  alias: {
    // Needed when library is linked via `npm link` to app
    react: path.resolve("./node_modules/react")
  }
}

“要求未定义”

这很可能发生,当您运行由错误的Webpack配置捆绑的web应用程序时,require调用不会被删除并被实际的代码模块替换。

如果应用程序项目基于create-react-app,则可以在app中导入库,只运行开始构建。给定自定义Webpack配置(例如通过eject),使用target:web (或省略target)运行构建,并省略externals: [ nodeExternals() ]

票数 27
EN

Stack Overflow用户

发布于 2019-08-15 22:27:37

这仅仅是因为您试图在React应用程序中使用您的库,这些应用程序运行的是与钩子不兼容的较旧版本的React吗?

我刚刚做了一个新的创建-反应-应用程序,添加了你的回购作为一个依赖于yarn add https://github.com/uchami/hooks-not-working,并没有问题,添加测试组件到默认的App.js

在回滚我的应用程序版本的React后,我只得到了一个错误。

票数 1
EN

Stack Overflow用户

发布于 2019-10-21 11:55:00

这也可能有帮助:反应钩重复反应包

我也有同样的问题,但更糟糕的是,我不得不用自己的语言管理多个应用程序。

该解决方案解决了所有的“多重反应库”错误。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57455200

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档