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

创建于 2019-04-04  ·  61评论  ·  资料来源: facebook/react

大家好,我是 React 的新手,我正在尝试创建一个组件的 React 库,我遇到了这个问题,因为我正在创建的组件之一使用REACT HOOKS

免责声明:这是我第一次创建问题,所以请耐心等待。

所以我试图创建一个手风琴组件,它在这些类accordion__item--openaccordion__item切换以打开和关闭。

包.json

{
  "name": "react-lib",
  "version": "0.3.0",
  "description": "A simple UI library of react components",
  "main": "dist/index.js",
  "publishConfig": {
    "registry": ""
  },
  "scripts": {
    "login": "",
    "build": "webpack --mode=production",
    "develop": "webpack --mode=development --watch"
  },
  "repository": {
    "type": "git",
    "url": ""
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "homepage": "",
  "dependencies": {
    "@babel/core": "^7.3.4",
    "@babel/preset-env": "^7.3.4",
    "@babel/preset-react": "^7.0.0",
    "babel-loader": "^8.0.5",
    "eslint": "^5.15.1",
    "eslint-loader": "^2.1.2",
    "webpack": "^4.29.6",
    "webpack-cli": "^3.2.3",
    "webpack-node-externals": "^1.7.2"
  },
  "devDependencies": {
    "eslint-config-airbnb": "^17.1.0",
    "eslint-plugin-import": "^2.16.0",
    "eslint-plugin-jsx-a11y": "^6.2.1",
    "eslint-plugin-react": "^7.12.4",
    "eslint-plugin-react-hooks": "^1.6.0"
  }
}

webpack.config.js

const path = require('path');
const webpack = require('webpack');

module.exports =  {

  mode: 'development',
  optimization: {
    minimize: true,
  },
  entry: './index.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'index.js',
    library: '',
    libraryTarget: 'commonjs'
  },
  target: 'node',
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules)/,
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-env', '@babel/react']
        }
      }
    ]
  } 
};

这是手风琴容器:

``
从“反应”导入反应;

功能手风琴({孩子}){

返回 (


{ 孩子们 }

);

}

导出默认手风琴;

**This is the accordion item that will live inside the container:** 

导入 React, { useState } from 'react';

功能手风琴项目({标题,内容}){

const [ isActive, toggleActive ] = useState(false);

返回 (

手风琴__item ${ isActive ? 'accordion__item--open' : '' } }>
  <button
    className="accordion__item-header"
    onClick={ () => isActive ? toggleActive(false) : toggleActive(true) }
  >
   { header }
   <svg className="icon icon--debit" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50">
     <path className="icon__path" d="M22.37,22.33V2.67a2.63,2.63,0,0,1,5.26,0V47.24a2.63,2.63,0,0,1-5.26.09V27.58H2.71a2.63,2.63,0,0,1,0-5.25Zm11.92,5.25a2.63,2.63,0,0,1,0-5.25h13a2.63,2.63,0,0,1,0,5.25Z">
     </path>
   </svg>
 </button>

 <div className="accordion__item-content">
   { children }
 </div>


)

};

导出默认 AccordionItem;

Now inside of a [create-react-app](https://github.com/sethandleah/myapp) I import these components

My [library](https://github.com/sethandleah/react-lib) and the [create-react-app](https://github.com/sethandleah/myapp) are relative to each other and I am using ```npm link```

从“反应”导入反应;

从“反应库”导入 {AccordionItem}
从'react-lib'导入{Accordion};

功能应用程序({道具}){

返回 (

  <Accordion>
    <AccordionItem header={"Hello"} content={"World"}/>
  </Accordion>

)

}

导出默认应用程序;

I have followed all of these [instructions](https://reactjs.org/warnings/invalid-hook-call-warning.html) and I still get the same error.


**Current behavior?**

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

  1. 你可能有不匹配的 React 版本和渲染器(例如 React DOM)
  2. 你可能会违反 Hooks 规则
  3. 您可能在同一个应用程序中拥有多个 React 副本
    有关如何调试和修复此问题的提示,请参阅https://fb.me/react-invalid-hook-call
**Steps to reproduce**

- clone [https://github.com/sethandleah/react-lib](https://github.com/sethandleah/react-lib)
- clone [https://github.com/sethandleah/myapp](https://github.com/sethandleah/myapp)
- ```cd react-lib```
- ```npm install```
- ```npm link```
- ```cd ../myapp```
- ```npm i```
- ```npm link react-lib```
- ```npm start```

**Expected behavior**

- It should show a button with a "plus" svg sign and the words "Hello" and "World" respectively
- Open devtools and go to elements
- When clicking on the button the class ```accordion_item--open``` should toggle

**To see the above, do the following:**

- Uncomment these lines at ```myapp/src/App.js```

从'./Accordion'导入手风琴;
从'./AccordionItem'导入手风琴项目;

- The comment out these line, alse at ```myapp/src/App.js```:

从'react-lib'导入{手风琴};
从'react-lib'导入{AccordionItem};
``

React、浏览器/操作系统的版本受此问题影响:

  • React 和 React-Dom:在react-libmyapp上都是^16.8.6
  • 浏览器:勇敢Version 0.61.52 Chromium: 73.0.3683.86 (Official Build) (64-bit)
  • 操作系统:MacOS High Siera Version 10.13.6 (17G5019)
Needs Investigation

最有用的评论

我的库和 create-react-app 是相对的,我使用的是 npm 链接

你读过这部分吗?

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

它直接解决了link工作流程:

Screen Shot 2019-04-04 at 09 28 47

所有61条评论

我认为您面临与https://github.com/facebook/react/issues/13991 中的人相同的问题,您能否看看问题最底部提出的一些解决方法,看看它们为你工作?

如果我在 HOC 中使用钩子,就会发生这种情况。

const HOC = Component => {
  return (props) => {
    const [val] = useState();
    return <div>{val}</div>
  }
}

@revskill10请使用代码和框重现单独提出问题。

我会推荐你​​使用https://www.npmjs.com/package/webpack-bundle-analyzer。

碰巧我们经常忘记将 react 和 react-dom 链接到父应用程序,以防库添加两个 react 构建并导致此问题。

如果是这种情况,那么不仅仅是 npm link react 和 react-dom 到 react 和 react-dom 的父版本。

我的库和 create-react-app 是相对的,我使用的是 npm 链接

你读过这部分吗?

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

它直接解决了link工作流程:

Screen Shot 2019-04-04 at 09 28 47

(如果这没有帮助,请告诉我,我们可以重新打开。我感谢详细的文章。)

谢谢大家的参与

@gaearon我已经根据 React 页面的建议尝试

我已按照所有这些说明进行操作,但仍然遇到相同的错误。

@threepointone很有趣,所以很多人在# 13991找到了解决方案,我昨天剩下的时间都在实施它们,但没有成功。

好的,如果这没有帮助,让我们将其打开,以便有人可以调试您的问题并帮助您。 问题 _is_ 相同(您链接包的方式导致它们在包中重复),但我不确定为什么该建议对您不起作用。

@gaearon你现在可以关闭它,上面的解决方案有效。

我只是以一种非常基本的方式调用 hook。

import React, {useState} from 'react'
import ReactDOM from 'react-dom'

function App() {
const [number, setNumber] = useState(0);
const increase = () => {
    setNumber(number+1);
}
return <div>
<span>Counting: {number}</span>
<button onClick={increase} >Increase</button>
</div>
}

const selector = document.getElementById('app');

ReactDOM.render(<App />, selector);

我收到错误
Hooks can only be called inside of the body of a function component.
我从草图创建了很多反应项目,但我以前从未遇到过这个错误。
我了解钩子的所有规则。
花了12个小时调试解决,可惜不行,现在不知道了。

// Add this in node_modules/react-dom/index.js
window.React1 = require('react');

// Add this in your component file
require('react-dom');
window.React2 = require('react');
console.log(window.React1 === window.React2); // I get true

@xeastcrast你能解决这个问题吗?

@carlosriveros
情况1:
你可能会检查你的 index.html 只有一个脚本标签包

如果你在检查 index.html 后得到同样的错误
案例2:
如果您使用 Webpack html,则在 webpack.config 文件中的 plugins 属性中
并且在 new HTMLWebpackPlugin() 选项中没有 {reject: true};

您必须在 index.html 中将 src 的脚本标记删除到您的包中

因为 HTMLWebpackPlugin 会自动添加包含你的包文件的脚本标签。

你好,我是 React Hooks 的新手。 我只是使用 Material-UI 在我的项目中创建搜索栏。 我写了这段代码,但这不起作用并给出了同样的问题。 我阅读了 React Hooks 文档,但对此一无所知。
反应代码
```从'react'导入React;
从'@material-ui/core/styles'导入{makeStyles};
从'@material-ui/core/Paper' 导入纸张;
从'@material-ui/core/InputBase' 导入 InputBase;
从 '@material-ui/core/IconButton' 导入 IconButton;
从'@material-ui/icons/Search' 导入 SearchIcon;

const useStyles = makeStyles({
根: {
填充:'2px 4px',
显示:'弹性',
alignItems: '中心',
宽度:400,
},
输入: {
左边距:8,
弹性:1,
},
图标按钮:{
填充:10,
},
分隔符:{
宽度:1,
身高:28,
保证金:4,
},
});

功能特征(){
const 类 = useStyles();

返回 (





);
}

导出默认功能;

**PACKAGE.JSON**
```{
  "name": "builder-frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@material-ui/core": "^4.0.1",
    "@material-ui/docs": "^3.0.0-alpha.9",
    "@material-ui/icons": "^4.0.0",
    "@material-ui/styles": "^4.0.1",
    "react": "^16.8.5",
    "react-dom": "^16.8.5",
    "react-redux": "^6.0.1",
    "react-router-dom": "^5.0.0",
    "react-scripts": "2.1.8",
    "redux": "^4.0.1",
    "styled-components": "^4.2.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ]
}

版本

  • 节点——v10.15.3
  • 反应——^16.8.5
  • Material-UI -- ^4.0.1

预期结果

  • 内置 VS CODE 和预期的_一个搜索栏_
    输出
    _TypeError: Object(...) 不是函数_
    _无效的钩子调用。 钩子只能在函数组件的主体内部调用。 这可能是由于以下原因之一造成的:_

尝试
_尝试在CODESANDBOX 中运行,一切正常_检查一下

你好,我是 React Hooks 的新手。 我只是使用 Material-UI 在我的项目中创建搜索栏。 我写了这段代码,但这不起作用并给出了同样的问题。 我阅读了 React Hooks 文档,但对此一无所知。
反应代码

import { makeStyles } from '@material-ui/core/styles';
import Paper from '@material-ui/core/Paper';
import InputBase from '@material-ui/core/InputBase';
import IconButton from '@material-ui/core/IconButton';
import SearchIcon from '@material-ui/icons/Search';

const useStyles = makeStyles({
  root: {
    padding: '2px 4px',
    display: 'flex',
    alignItems: 'center',
    width: 400,
  },
  input: {
    marginLeft: 8,
    flex: 1,
  },
  iconButton: {
    padding: 10,
  },
  divider: {
    width: 1,
    height: 28,
    margin: 4,
  },
});

function Feature() {
    const classes = useStyles();

  return (
    <Paper className={classes.root}>
      <InputBase className={classes.input} placeholder="Search Google Maps" />
      <IconButton className={classes.iconButton} aria-label="Search">
        <SearchIcon />
      </IconButton>
    </Paper>
  );
}

export default Feature;

包.JSON

  "name": "builder-frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@material-ui/core": "^4.0.1",
    "@material-ui/docs": "^3.0.0-alpha.9",
    "@material-ui/icons": "^4.0.0",
    "@material-ui/styles": "^4.0.1",
    "react": "^16.8.5",
    "react-dom": "^16.8.5",
    "react-redux": "^6.0.1",
    "react-router-dom": "^5.0.0",
    "react-scripts": "2.1.8",
    "redux": "^4.0.1",
    "styled-components": "^4.2.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ]
}

版本

  • 节点——v10.15.3
  • 反应——^16.8.5
  • Material-UI -- ^4.0.1

预期结果

  • 内置 VS CODE 和预期的_一个搜索栏_
    输出
    _TypeError: Object(...) 不是函数_
    _无效的钩子调用。 钩子只能在函数组件的主体内部调用。 这可能是由于以下原因之一造成的:_

尝试
_尝试在CODESANDBOX 中运行,一切正常_检查一下

我在使用material-ui的时候也遇到这个问题。

@stupidsongshu ,你是怎么解决的?

你好,我是 React Hooks 的新手。 我只是使用 Material-UI 在我的项目中创建搜索栏。 我写了这段代码,但这不起作用并给出了同样的问题。 我阅读了 React Hooks 文档,但对此一无所知。
反应代码

import { makeStyles } from '@material-ui/core/styles';
import Paper from '@material-ui/core/Paper';
import InputBase from '@material-ui/core/InputBase';
import IconButton from '@material-ui/core/IconButton';
import SearchIcon from '@material-ui/icons/Search';

const useStyles = makeStyles({
  root: {
    padding: '2px 4px',
    display: 'flex',
    alignItems: 'center',
    width: 400,
  },
  input: {
    marginLeft: 8,
    flex: 1,
  },
  iconButton: {
    padding: 10,
  },
  divider: {
    width: 1,
    height: 28,
    margin: 4,
  },
});

function Feature() {
    const classes = useStyles();

  return (
    <Paper className={classes.root}>
      <InputBase className={classes.input} placeholder="Search Google Maps" />
      <IconButton className={classes.iconButton} aria-label="Search">
        <SearchIcon />
      </IconButton>
    </Paper>
  );
}

export default Feature;

包.JSON

  "name": "builder-frontend",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@material-ui/core": "^4.0.1",
    "@material-ui/docs": "^3.0.0-alpha.9",
    "@material-ui/icons": "^4.0.0",
    "@material-ui/styles": "^4.0.1",
    "react": "^16.8.5",
    "react-dom": "^16.8.5",
    "react-redux": "^6.0.1",
    "react-router-dom": "^5.0.0",
    "react-scripts": "2.1.8",
    "redux": "^4.0.1",
    "styled-components": "^4.2.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject"
  },
  "eslintConfig": {
    "extends": "react-app"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ]
}

版本

  • 节点——v10.15.3
  • 反应——^16.8.5
  • Material-UI -- ^4.0.1

预期结果

  • 内置 VS CODE 和预期的_一个搜索栏_
    输出
    _TypeError: Object(...) 不是函数_
    _无效的钩子调用。 钩子只能在函数组件的主体内部调用。 这可能是由于以下原因之一造成的:_

尝试
_尝试在CODESANDBOX 中运行,一切正常_检查一下

今天发生在我身上,我只是运行 npm install --save react-dom@latest

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

我按照帮助页面中提供的说明进行操作,但仍然没有解决问题

对我来说,我们现在通过简单地将 React 作为 prop 传递来解决它。 这是一个我们完全控制的应用程序和单独的模块,所以我不知道它是否适用于每个人。

它也没有帮助我..
使用 React & React-DOM = 16.8.0 和 Material-UI = 4.1.3

我一直在测试关于这个钩子问题的所有解决方案,任何使用钩子从外部库导入组件都会崩溃,因为有 2 个反应实例(一个来自库,一个来自我的应用程序)。

我遵循了所有建议,到目前为止没有任何效果。 我将使用状态制作组件,直到它得到进一步澄清......

同样的问题在这里。 我们有一个包含两个 react 实例的项目。 一个作为lib和一个app正在消耗lib

我通过删除yarn.lockpackage-lock.jsonnode_modulesdist等缓存和构建文件来解决,然后运行yarnnpm install再次安装库。 现在它起作用了!

我通过改变来解决这个问题

                <Route key={index} render={route.component} path={route.path} />

                <Route key={index} component={route.component} path={route.path} />

但我不知道为什么:(

通过使用组件而不是错误渲染来修复。 官方指南没有提到这种情况。
谢谢,xyj404
<Route path="/login" exact component={LoginForm} />

我有同样的问题,但原因不同。 对于使用自动导入插件或片段的任何人,请确保从同一个案例中导入。

如果您混合使用import {useEffect} from 'react'import {useEffect} from 'React'您将遇到此问题。

我也有这个问题,虽然在故事书中对我来说一切正常,但是在应用程序中使用时它给出了同样的错误

同样的问题也有效
在故事书中很好,但使用该应用程序会引发此错误

同样的错误,我在运行npm test时得到它,但应用程序运行良好。
这是我的package.json ,有什么建议吗? 我真的被卡住了,浪费时间处理这个错误

{
  "name": "myproject",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@date-io/moment": "1.0.1",
    "@material-ui/core": "^3.9.3",
    "@material-ui/icons": "^3.0.1",
    "animate.css": "^3.7.0",
    "aws-amplify": "^0.4.8",
    "aws-amplify-react": "^0.1.54",
    "axios": "^0.18.0",
    "file-saver": "^2.0.0",
    "ics-js": "^0.10.2",
    "material-ui-pickers": "2.1.1",
    "moment": "^2.23.0",
    "normalize.css": "^8.0.1",
    "react": "^16.8.6",
    "react-app-polyfill": "^1.0.0",
    "react-date-range": "^1.0.0-beta",
    "react-dom": "^16.8.6",
    "react-google-maps": "^9.4.5",
    "react-jss": "^8.6.1",
    "react-router": "^4.3.1",
    "react-router-dom": "^4.3.1",
    "react-scripts": "3.0.1",
    "recharts": "^1.3.5",
    "redux": "^4.0.1",
    "styled-components": "^4.2.0",
    "sweetalert2": "^7.33.1",
    "sweetalert2-react-content": "^1.0.1"
  },
  "scripts": {
    "start:dev": "node  -r dotenv/config ./node_modules/react-scripts/bin/react-scripts start dotenv_config_path=./env/development.env",
    "start:stage": "node -r dotenv/config ./node_modules/react-scripts/bin/react-scripts start dotenv_config_path=./env/stage.env",
    "start:prod": "node -r dotenv/config ./node_modules/react-scripts/bin/react-scripts start dotenv_config_path=./env/production.env",
    "build:stage": "node --max_old_space_size=2048 --max_old_space_size=1024 -r dotenv/config ./node_modules/.bin/react-scripts build dotenv_config_path=./env/stage.env",
    "build:dev": "node --max_old_space_size=2048 -r dotenv/config ./node_modules/react-scripts/bin/react-scripts build dotenv_config_path=./env/development.env",
    "build:prod": "node --max_old_space_size=2048 -r dotenv/config ./node_modules/react-scripts/bin/react-scripts build dotenv_config_path=./env/production.env",
    "test": "node -r dotenv/config ./node_modules/.bin/react-scripts test dotenv_config_path=./env/development.env --runInBand",
    "eject": "react-scripts eject"
  },
  "devDependencies": {
    "@testing-library/jest-dom": "^4.0.0",
    "@testing-library/react": "^8.0.5",
    "@testing-library/react-hooks": "^1.1.0",
    "dotenv": "^6.0.0",
    "prettier": "^1.15.3",
    "react-test-renderer": "^16.8.6"
  },
  "browserslist": [
    ">0.2%",
    "not dead",
    "not ie <= 11",
    "not op_mini all"
  ]
}

使用 react 和 react-dom v16.8.6 也遇到了这种情况,在使用 npm link 链接的单独应用程序中使用@material-ui/core中的makeStyles钩子。

将主应用程序升级为 react 和 react-dom v16.9.0,并重新链接使用导致问题的钩子的应用程序后,一切又开始工作了。

是的,我在使用 @material-ui 时遇到了同样的问题。 解决这个问题需要更多时间。 然后我搜索了谷歌并找到了解决方案。 它在这里http://putridparrot.com/blog/react-material-ui-invalid-hook-call-hooks-can-only-be-Called-inside-of-the-body-of-a-function-component/

原帖:

在查看一些在 React 中编写 Material UI 代码并使用 TypeScript(准确地说是在 .tsx 文件中)的示例时,您可能会在运行时遇到错误,例如“Invalid hook call。 钩子只能在函数组件的主体内部调用”。

这是导致此错误的代码示例

import React, { Component }  from "react";
import AddIcon from "@material-ui/icons/Add";
import { Fab } from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";

const useStyles = makeStyles(theme => ({
   fab: {
      margin: theme.spacing(1),
   },
}));

const classes = useStyles();

export default class SampleComponent extends Component<{}, {}> {
   public render() {
      return (
         <div>
            <Fab color="primary" aria-label="Add" className={classes.fab}><AddIcon /></Fab>
         </div>
       );
   }
}

我们需要做的是将 useStyles 代码包装在一个函数中并替换使用它的代码,例如

const SampleFab = () => {
   const classes = useStyles();
   return <Fab color="primary" aria-label="Add" className={classes.fab}><AddIcon /></Fab>;
}

export default class SampleComponent extends Component<{}, {}> {
   public render() {
      return (
         <div>
            <SampleFab />
         </div>
      );
   }
}

这也展示了我们如何从一个简单的函数中创建可重用的组件。

=> 这很疯狂,但运行良好。 希望这能有所帮助。

如果您正在使用 lerna 或像我这样的 monorepo,请将这样的东西添加到您的 Webpack 解析配置中

...
    alias: {
      'react-dom': 'path/to/main-package/node_modules/react-dom',
      react: 'path/to/main-package/form/node_modules/react',
    }
...

如果你在 Storybook 中得到它,也将它添加到自定义 Webpack 配置中。

附带说明,如果这为您解决了问题,则您的 webpack 构建包中也有 2 个版本的 react(使用 sth 之类的 webpack 包分析器来检查它)。 就我而言,我的 monorepo 中有一个单独的包,负责捆绑和所有工具,因此我不得不添加别名。

如果您正在使用 lerna 或像我这样的 monorepo,请将这样的东西添加到您的 Webpack 解析配置中

...
    alias: {
      'react-dom': 'path/to/main-package/node_modules/react-dom',
      react: 'path/to/main-package/form/node_modules/react',
  }
...

如果你在 Storybook 中得到它,也将它添加到自定义 Webpack 配置中。

附带说明,如果这为您解决了问题,则您的 webpack 构建包中也有 2 个版本的 react(使用 sth 之类的 webpack 包分析器来检查它)。 就我而言,我的 monorepo 中有一个单独的包,负责捆绑和所有工具,因此我不得不添加别名。

谢谢,这解决了我的问题,我在docs字典中安装了另一个 React,这导致了这个问题。

我只是以一种非常基本的方式调用 hook。

import React, {useState} from 'react'
import ReactDOM from 'react-dom'

function App() {
const [number, setNumber] = useState(0);
const increase = () => {
    setNumber(number+1);
}
return <div>
<span>Counting: {number}</span>
<button onClick={increase} >Increase</button>
</div>
}

const selector = document.getElementById('app');

ReactDOM.render(<App />, selector);

我收到错误
Hooks can only be called inside of the body of a function component.
我从草图创建了很多反应项目,但我以前从未遇到过这个错误。
我了解钩子的所有规则。
花了12个小时调试解决,可惜不行,现在不知道了。

// Add this in node_modules/react-dom/index.js
window.React1 = require('react');

// Add this in your component file
require('react-dom');
window.React2 = require('react');
console.log(window.React1 === window.React2); // I get true

你可能有不匹配的 React 和 React DOM 版本。
我通过更改 React 版本解决了同样的问题

当我尝试将我的组件从功能性组件更改为 classfull 组件时,我遇到了这个问题,我也遇到了这个错误,所以这是我关于这个错误的解决方案,希望它也对你的情况有所帮助。

在这种情况下尝试使用高阶组件

从“反应”导入反应;
从 'prop-types' 导入 PropTypes;
从'@material-ui/styles' 导入 { withStyles };
从“@material-ui/core/Button”导入按钮;

const 样式 = 主题 => ({
根: {
背景:'线性梯度(45度,#FE6B8B 30%,#FF8E53 90%)',
边界:0,
边界半径:3,
boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .3)',
白颜色',
身高:48,
填充:'0 30px',
},
});

class HigherOrderComponent 扩展了 React.Component {

使成为(){
const { 类} = this.props;
返回 (

HigherOrderComponent.propTypes = {
类:PropTypes.object.isRequired,
};

导出默认 withStyles(styles)(HigherOrderComponent);

我正在学习 React 和 FWIW,在尝试像这样渲染 App() 时我也看到了这个问题:

ReactDOM.render(App(), $("#root"));

我的理由是<App />会隐式地创建一个迷你模板来插入 App 组件,所以我只是直接调用 App,它返回 JSX 模板。

但是,一旦我开始使用 setState(),就会导致上述问题。 更改为<App />解决了这个问题。

ReactDOM.render(<App />, $("#root"));

注意:$ 只是一个帮手const $ = sel => document.querySelector(sel);

对于那些在对所有建议的修复程序进行故障排除后仍然遇到此错误的人,请仔细检查您在运行项目时是否使用了正确的目录大小写。 我的 PC 继续出现问题,并发现这就是原因。

https://stackoverflow.com/questions/58365151/hooks-error-invalid-hook-call-using-nextjs-or-reactjs-on-windows

react-dom更新到版本16.10.2后运行测试时出现该错误。 将enzyme-adapter-react-16升级到版本1.15.1修复了它

哦,伙计,我正在使用 React v16.10.2。 我已经花了几个小时试图解决这个问题,但我不会再继续这场战斗了,因为我有更重要的事情要做。 我现在可以继续使用 react-final-form 4.1.0。 多么令人沮丧。

在升级依赖项后,我刚刚遇到了同样的问题,并花了几个小时试图解决这个问题。

npm ls react显示如下:

├─┬ @storybook/[email protected]
│ └── [email protected]
└── [email protected]

reactreact-dom16.9.0会使错误消失,因为它使瞬态依赖消失。 我最初认为这意味着16.10.0存在回归,直到我注意到16.8.6也出现了问题(因为瞬态依赖显然已被固定)。

事实证明,yarn 的resolutions字段对于正常工作来说有点挑剔,尤其是在 lerna monorepos 中,但是去掉 React 的第二个副本就成功了。 我仍然不知道它是如何最终出现在捆绑包中的,但这就是导致问题的原因。

我现在正在考虑完全删除@storybook/addon-info因为它也依赖于另一个依赖于 React 0.14 的依赖(是的),尽管那个依赖还没有引起问题。

编辑:为了记录,我花了大约四个小时来解决这个问题,因为我无法得到resolutions来消除重复项,并且拒绝相信 React 的副本甚至进入了捆绑包。 不要像我一样。 对您的瞬态 React 进行重复数据删除。

如果我在 HOC 中使用钩子,就会发生这种情况。

const HOC = Component => {
  return (props) => {
    const [val] = useState();
    return <div>{val}</div>
  }
}

我也面临同样的问题。

https://stackoverflow.com/questions/59173968/react-error-hooks-can-only-be-Called-inside-the-body-of-a-function-component?noredirect=1#comment104570333_59173968

你能指导我吗?

@Neeraj-swarnkar 尝试将您的问题减少到仍然导致错误的最小示例。

它几乎总是归结为两个问题之一:

  • 你认为你正在传递一个组件,但它实际上是一个渲染道具(即“组件”被称为一个函数,而不是一个组件)
  • 你以某种方式通过你的瞬态依赖捆绑了不止一个版本的 React,它们相互踩踏

遗憾的是,在这种情况下,堆栈跟踪往往会产生误导,但错误消息通常会为您提供正确的想法。

@Neeraj-swarnkar 尝试将您的问题减少到仍然导致错误的最小示例。

它几乎总是归结为两个问题之一:

  • 你认为你正在传递一个组件,但它实际上是一个渲染道具(即“组件”被称为一个函数,而不是一个组件)
  • 你以某种方式通过你的瞬态依赖捆绑了不止一个版本的 React,它们相互踩踏

遗憾的是,在这种情况下,堆栈跟踪往往会产生误导,但错误消息通常会为您提供正确的想法。

谢谢你的指点,你能指导我什么可以做得更好,或者我应该怎么做才能解决这个问题?

@Neeraj-swarnkar 尝试注释掉代码并用占位符替换它,直到您有一个仍然导致相同错误的最小示例。

如果您没有同事或同行,您可以要求协助您进一步调试,看看您是否可以找到当地的聚会、学习小组或开放办公时间的公司,并向他们寻求帮助。 如果所有其他方法都失败了,请雇人为您调查。

我的库和 create-react-app 是相对的,我使用的是 npm 链接

你读过这部分吗?

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

它直接解决了link工作流程:

Screen Shot 2019-04-04 at 09 28 47

这项工作就像一个魅力!

我的库和 create-react-app 是相对的,我使用的是 npm 链接

你读过这部分吗?

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

它直接解决了link工作流程:

Screen Shot 2019-04-04 at 09 28 47

这项工作就像一个魅力!

昨天解决了这个问题,困扰了我半个月。昨天我把代码缩短到很少(只需添加

我通过改变来解决这个问题

                <Route key={index} render={route.component} path={route.path} />

                <Route key={index} component={route.component} path={route.path} />

但我不知道为什么:(

它确实对我有用,但我也不知道为什么。

如果您来到这里是因为您使用的是 Material UI 中的 HOC + makeStyles
这是你的答案: https :

我通过改变来解决这个问题

                <Route key={index} render={route.component} path={route.path} />

                <Route key={index} component={route.component} path={route.path} />

但我不知道为什么:(

它确实对我有用,但我也不知道为什么。

“component” prop 需要一个 React 组件,“render” prop 需要一个将作为函数调用的函数。 函数组件是组件,如果它们使用钩子,则将它们作为普通函数调用将不起作用,并且通常不是一个好主意。

我通过改变来解决这个问题

                <Route key={index} render={route.component} path={route.path} />

                <Route key={index} component={route.component} path={route.path} />

但我不知道为什么:(

谢谢,亲爱的,它对我有用,但是,我很困惑,为什么?

@jaisonjjames看到我的回复。 如果您在理解差异时遇到困难,StackOverflow 上有一些解释: https :

就我而言,我在组件外有let match = useRouteMatch("/user/:id"); ,它是 react-router 的一个钩子,所以错误是正确的。



<Route path="/component" component={myComponent} />

<Route path="/component"><myComponent /></Route>

在我的例子中,我指的是window对象中的一个库,它有不同的 React 版本。 我最终使用了 webpack 中的externals配置选项,它帮助我引用了该库的reactreact-dom并使错误消失。

所以我相信我收到这个错误的原因是因为You might have more than one copy of React in the same app

在我的例子中,我指的是window对象中的一个库,它有不同的 React 版本。 我最终使用了 webpack 中的externals配置选项,它帮助我引用了该库的reactreact-dom并使错误消失。

所以我相信我收到这个错误的原因是因为You might have more than one copy of React in the same app

@AbreezaSaleem你是如何做到这一点的? 我有同样的问题,使用具有react作为外部的库以某种方式显示为不同的版本......我试过externals: [ 'react' ]externals: { react: 'react' }externals: { react: 'React' } ,结果总是一样的......

我创建了一个最小的例子来重现这个。 在我的情况下,问题发生在带有电子 webpack 和 react-dropzone 的 ElectronJS 上

https://github.com/JuanIrache/dropzone-test

有一个很好的 webpack 配置解决方案指向相同/单个反应实例。 它是在使用“成为 npm 模块”的应用程序中添加分辨率。

在 webpack.config.js 中,添加别名来反应 - 所以它使用那个反应实例:

module.exports = {
resolve: {
    alias: {
      react: path.resolve('./node_modules/react')
    }
  },
 // other webpack settings
}

lerna 会导致这个问题,正如我今天学到的(学习?)。

lerna 用户,如果你正在开发一个组件库,不要在你的库的依赖项中包含 react,把它放在你的 peerDependencies 和 @types/react 在你的 devDependencies 中。

对于任何使用 lerna 的人来说,在一个包中运行测试时可能会遇到这个问题,其中代码引用了另一个包中的组件。

我们在这种情况下遇到的问题是由于 react 被导入到规范中,并且还被导入到组件树中使用Material UI 的 withStyles的组件中,该组件是使用

似乎 react 在内部管理ReactCurrentDispatcher.current变量中的状态,这最终在一个 react 实例中设置,但在另一个 react 实例中使用 - 当它为空时,它会抛出Invalid hook call ...消息。

我们已经在构建时使用Craco来覆盖 Create React App 的 webpack 配置:

  webpack: {
    alias: {
      react: path.resolve(__dirname, './node_modules/react'),
    },
  },

然而,这个 webpack 覆盖只在构建时使用——运行测试时,代码不是构建的,而是从源代码实例化的——所以我们的解决方案是在craco.config.js使用CracoAlias来指定测试期间的反应路径:

  plugins: [
    {
      plugin: CracoAlias,
      options: {
        source: 'options',
        baseUrl: './',
        aliases: {
          // We need to alias react to the one installed in the desktop/node_modules
          // in order to solve the error "hooks can only be called inside the body of a function component"
          // which is encountered during desktop jest unit tests,
          // described at https://github.com/facebook/react/issues/13991
          // This is caused by two different instances of react being loaded:
          // * the first at packages/desktop/node_modules (for HostSignUpDownloadComponent.spec.js)
          // * the second at packages/components/node_modules (for packages/components/Modal)
          react: './node_modules/react',
        },
      },
    },
  ],
此页面是否有帮助?
0 / 5 - 0 等级