React库中的React hooks出现"Invalid hook call error"错误

42

我使用https://www.npmjs.com/package/create-react-library创建了一个React库。 并已成功地在其他React项目中使用它。 但当我尝试在库中使用React Hooks功能时,会出现以下错误。

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
.....

我的图书馆 我刚尝试在我的组件中使用useState,代码如下。

import React, { useState } from 'react'

const General = (props) => {

    const [count, setCount] = useState(0);
    return (
        <div>
           General component
        </div>
    )
}

export default General

我正在使用"react": "^16.8.6""react-dom": "^16.8.6"

我的React应用是使用https://github.com/facebook/create-react-app创建的,并按以下方式使用上述库。

import Reactfrom 'react'
import { General } from 'my.lib'
const accountSummary = props => {

  return (
    <div>
      <General>
    </div>
  )
}

export default accountSummary

两者使用了相同的React版本,并且库也使用了与peerDependencies中相同的React DOM和React版本。


你正在使用哪些版本的 React 和 React DOM? - Joe Clay
@Vencovsky,我违反了什么规则?我一点都不清楚。 - Janith Widarshana
1
问题出在我正在本地运行库,并使用 "my.library": "file:../my.library" 在 py package.json 中引用它。Lib 在另一个 React 实例中单独运行。如果我将其作为 npm 库发布并使用它,则可以正常工作。 - Janith Widarshana
1
这就是你违反规则的方式...... 你在一个组件(MyLibrary的组件之一)中使用了一个钩子(比如useState),它由Rollup打包到dist/index.js中(默认由create-react-library配置)。当进行打包时,你的钩子可能被推到某个条件中(比如if语句),导致规则被破坏! - Yugandhar Pathi
2
@YugandharPathi 如果是这样,那么解决方案是什么?我认为我可能遇到了同样的问题。React 不可能如此脆弱,无法处理捆绑,对吗? - Dave
显示剩余6条评论
10个回答

68

我正在将我的组件库(或者任何库)作为@Janith所做的方式包含在应用程序中,使用my-comp-lib:"file:../.."(我不想每次测试时都要发布),然后我遇到了相同的问题。

无效的钩子调用。钩子只能在函数组件的主体内被调用。这可能是以下原因之一:

  1. React和渲染器(如React DOM)的版本可能不匹配
  2. 您可能违反了Hooks的规则
  3. 您可能在同一个应用程序中拥有多个React副本,请参阅react-invalid-hook-call以获取有关如何调试和解决此问题的提示

修复此问题,我通过使我的应用程序和库指向相同的React(软件包)位置来解决了它。

Below are the steps I followed :
1. In Your Application:
a) cd node_modules/react && npm link
b) cd node_modules/react-dom && npm link

2. In Your Library
a) npm link react
b) npm link react-dom

3)Stop your dev-server and do `npm start` again.

它起作用了!!

有关更多详细信息,请参考以下链接..

https://github.com/facebook/react/issues/14721

https://github.com/facebook/react/pull/14690

https://github.com/facebook/react/issues/13991

注意:如果您将软件包发布到存储库并进行安装,则不会出现此问题,因为您将具有 react 和 react-dom 作为对等依赖项,并且它们不会包含在发行版中。 因此,您的软件包和应用程序使用相同的在应用程序中安装的react。


3
顺便提一句,更简洁的解决方案是从库文件夹运行此命令: "npm link ../web-application/node_modules/react"。这是假设库和Web应用程序在同级文件夹中。如果库还需要使用react-dom,则可以使用类似的命令。 - kas
2
@yugandhar-pathi,非常感谢您提供的解决方案! - jashgopani
2
谢谢您的答案,它确实很有帮助。 - vdua
1
你是一个神!!! - Jishnu Raj
1
你真是太厉害了! - undefined
显示剩余3条评论

6

我也遇到了同样的问题,正在使用rush monorepo配置ui-package,并使用nextjs构建应用程序。

解决方法是在package.json中添加以下代码:

"resolutions": {
  "react": "17.0.1", // verificate your react version
  "react-dom": "17.0.1"
}

在图书馆的 package.json 文件中:
"peerDependencies": {
   "react": "17.0.1",
   "react-dom": "17.0.1"
 },

更多内容请参见:https://github.com/vercel/next.js/issues/9022#issuecomment-728688452


对我来说不起作用。 - TheKalashnikov

6

我遇到了同样的问题。我通过将示例应用程序中的react指向我的库中的相同react来解决它:

应用程序结构

根目录

  • 示例
    • package.json
  • src(库)
  • package.json

因此,从示例 > package.json文件中,我将react更改为:

    "react": "link:../node_modules/react",

这很类似于上面提到的npm link,但它不会在每次npm install时消失。

是的,这对我来说是解决上述问题的方法。 - Janith Widarshana
3
请注意,较新版本的npm已弃用link。相反,您需要使用file: "react": "file:../node_modules/react" - RyanNerd

4

0

当我将应用程序链接到库的链接从"file:../"更改为"link:../"时,它对我有用,并且还链接了 react 和 react-dom。


3
当我尝试这样做时,出现了“不支持的 URL 类型‘link:’”错误。我的 npm 版本是 6.4.1。 - Ben Clayton

0

在使用React Native进行真实应用测试时

我有同样的问题,我删除了自定义库中的node_module文件,并解决了问题。

在安装直接模块时出现问题

yarn add c:/user......./react-native-some-lib


0

React 17 + React Testing Library + Umi(一个内置react-router的前端框架)

在我的情况下,当我运行单元测试时,我收到了一个“无效的hook调用”错误消息。

经过一段时间的尝试,我找到了两种解决方法。

  1. 降级到React 16.x,然后一切都会好起来。
  2. 继续使用React 17.x,并且
    • 仍需编写import React from 'react'
    • 单独安装react-router-dom

我认为这可能是与react-router有关的问题,但由于我的理解有限,我还没有更好的解决方案。


0
此外,还要检查您的npm版本。我的版本是7.0.8,已经过时了,将其更改为6.14.8后,一切都正常工作了!

0
在我的情况下,我正在构建自己的通用库。虽然我从 "react" 导出了 createContext、useContext 和 useState,但我简单地忘记了也导入默认导出的 React。
将我的导入语句从这个:
import { createContext, useContext, useState } from "react"; 更改为这个:
import React, { createContext, useContext, useState } from "react"; 对我来说解决了问题。您可能需要在从 react 库中导出的每个 React 组件/上下文等中执行此操作。
编辑:
在我使用这个通用库的另一个应用程序中,也使用了 React 文档中描述的 npm link 来解决此问题(Invalid Hook Call Warning)。
这个问题也可能在使用npm link或等效操作时出现。在这种情况下,您的打包程序可能会“看到”两个React——一个在应用程序文件夹中,另一个在库文件夹中。假设myapp和mylib是兄弟文件夹,一种可能的解决方法是从mylib运行npm link ../myapp/node_modules/react。这样可以使库使用应用程序的React副本。

因此,在我的情况下,我导航到我的公共库并运行了npm link ../path-to-my-app/node_modules/react

编辑(2022年2月23日)

希望这是最终版-另一种解决方案是如果所有应用程序都期望使用相同版本,则简单地全局安装有问题的依赖项,例如npm install react -g


-2

我使用create-react-library创建了一个React库,这个库是你的General组件。我已经将它发布到npm上,链接在这里https://www.npmjs.com/package/stackoverflow-test,并且为了使用它而创建了一个React应用程序,链接在这里https://codesandbox.io/s/mm7yl83o28

只需点击General component文本,count就会增加。

我无法重现你的问题,只需使用这个测试来检查你的实现。


最后我找到了问题所在。我将"react-scripts"安装到我的React应用程序中,现在它可以正常工作了。 - Janith Widarshana
很好,那就是缺少数据包的问题。 - F.bernal
问题出在我本地运行库时,使用了 "my.library": "file:../my.library" 的引用方式。该库在另一个React实例中单独运行。如果我将其发布为npm库并使用它,则可以正常工作。 - Janith Widarshana
你在 stackoverflow-test 中的组件(比如 <General/>)里使用了 hook 吗? - Yugandhar Pathi
@YugandharPathi 是的 - F.bernal
只有在使用文件:../包含本地库时才会出现此问题。 - Yugandhar Pathi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接