ChatGPT解决这个技术问题 Extra ChatGPT

无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用

我想使用 React 在表中显示一些记录,但出现此错误:

无效的挂钩调用。钩子只能在函数组件的主体内部调用。这可能是由于以下原因之一: 您可能有不匹配的 React 版本和渲染器(例如 React DOM) 您可能违反了 Hooks 规则 您可能在同一个应用程序中拥有多个 React 副本 请参阅提示关于如何调试和解决这个问题。

import React, {
  Component
} from 'react';
import {
  makeStyles
} from '@material-ui/core/styles';
import Table from '@material-ui/core/Table';
import TableBody from '@material-ui/core/TableBody';
import TableCell from '@material-ui/core/TableCell';
import TableHead from '@material-ui/core/TableHead';
import TableRow from '@material-ui/core/TableRow';
import Paper from '@material-ui/core/Paper';

const useStyles = makeStyles(theme => ({
  root: {
    width: '100%',
    marginTop: theme.spacing(3),
    overflowX: 'auto',
  },
  table: {
    minWidth: 650,
  },
}));

class allowance extends Component {
  constructor() {
    super();
    this.state = {
      allowances: [],
    };

  }

  componentWillMount() {
    fetch('http://127.0.0.1:8000/allowances')
      .then(data => {

        return data.json();

      }).then(data => {

        this.setState({
          allowances: data
        });

        console.log("allowance state", this.state.allowances);
      })

  }



  render() {
    const classes = useStyles();
    return ( <
      Paper className = {
        classes.root
      } >
      <
      Table className = {
        classes.table
      } >
      <
      TableHead >
      <
      TableRow >
      <
      TableCell > Allow ID < /TableCell> <
      TableCell align = "right" > Description < /TableCell> <
      TableCell align = "right" > Allow Amount < /TableCell> <
      TableCell align = "right" > AllowType < /TableCell>

      <
      /TableRow> <
      /TableHead> <
      TableBody > {
        this.state.allowances.map(row => ( <
          TableRow key = {
            row.id
          } >
          <
          TableCell component = "th"
          scope = "row" > {
            row.AllowID
          } <
          /TableCell> <
          TableCell align = "right" > {
            row.AllowDesc
          } < /TableCell> <
          TableCell align = "right" > {
            row.AllowAmt
          } < /TableCell> <
          TableCell align = "right" > {
            row.AllowType
          } < /TableCell>                     <
          /TableRow>
        ))
      } <
      /TableBody> <
      /Table> <
      /Paper>
    );
  }

}

export default allowance;

t
theVoogie

当我使用 npm link 安装我使用 cra 构建的本地库时,我遇到了这个问题。我找到了答案 here。字面意思是:

当您使用 npm link 或等效项时,也会出现此问题。在这种情况下,你的打包器可能会“看到”两个 React——一个在应用程序文件夹中,一个在你的库文件夹中。假设“myapp”和“mylib”是同级文件夹,一种可能的解决方法是从“mylib”运行“npm link ../myapp/node_modules/react”。这应该使库使用应用程序的 React 副本。

因此,运行命令:npm link <path_to_local_library>/node_modules/react,例如。在我的情况下,项目目录中的 npm link ../../libraries/core/decipher/node_modules/react 已经解决了这个问题。


谢了哥们!你救了我的一天!所有通过 npm/yarn 链接使用本地包的人,请遵循此!
这对我有用。这是我的确切问题。
那么在npm上发布就会报错吧?或者可能没有,因为它是链接的,在我的机器上它将使用来自链接的反应,并且在发布后,它将使用它自己的。 🤔
长期以来,使用链接到本地库的 cra 处理应用程序,我永远不会看到此错误消息。只需在两个项目上运行 npm i,然后再次运行 npm link,就可以了。
我花了 8 个小时来解决这个问题,并尝试以不同的方式完成该功能。太感谢了
A
Aryan Beezadhur

你只能从 React 函数中调用钩子。阅读更多here

只需将 Allowance 类组件转换为功能组件即可。

Working CodeSandbox demo

const Allowance = () => {
  const [allowances, setAllowances] = useState([]);

  useEffect(() => {
    fetch("http://127.0.0.1:8000/allowances")
      .then(data => {
        return data.json();
      })
      .then(data => {
        setAllowances(data);
      })
      .catch(err => {
        console.log(123123);
      });
  }, []);

  const classes = useStyles();
  return ( <
    Paper className = {
      classes.root
    } >
    <
    Table className = {
      classes.table
    } >
    <
    TableHead >
    <
    TableRow >
    <
    TableCell > Allow ID < /TableCell> <
    TableCell align = "right" > Description < /TableCell> <
    TableCell align = "right" > Allow Amount < /TableCell> <
    TableCell align = "right" > AllowType < /TableCell> <
    /TableRow> <
    /TableHead> <
    TableBody > {
      allowances.map(row => ( <
        TableRow key = {
          row.id
        } >
        <
        TableCell component = "th"
        scope = "row" > {
          row.AllowID
        } <
        /TableCell> <
        TableCell align = "right" > {
          row.AllowDesc
        } < /TableCell> <
        TableCell align = "right" > {
          row.AllowAmt
        } < /TableCell> <
        TableCell align = "right" > {
          row.AllowType
        } < /TableCell> <
        /TableRow>
      ))
    } <
    /TableBody> <
    /Table> <
    /Paper>
  );
};

export default Allowance;

有一件事想问你,调用setAllowances(data)后,津贴应该有数据吧?否则,当津贴有数据时?
是的。在调用 setAllowances(data) 之后。 setAllowancesthis.setState({allowances: data}) 一样工作
我有点困惑,在调用 setAllowances(data) 之后,我尝试使用 console.log("data",data);这有 3 条记录,但如果我尝试使用 console.log("allowance",allowances);这没什么记录。我可以知道为什么吗?您可以在您的代码示例中尝试。
原因 setAllowances 像 this.setState 一样是异步的。因此您在 setAllowances 之后记录 allowances,它将记录 old allowances
在作者的零用钱中,他们在哪里叫钩子?
l
luiz carlos batista

您可以通过调用一个箭头函数来使用“导出默认值”,该函数通过 MaterialUI 类对象道具传递它返回其 React.Component,而后者又将在组件渲染()中使用。

class AllowanceClass extends Component{
    ...
    render() {
        const classes = this.props.classes;
        ...
    }
}

export default () => {
    const classes = useStyles();
    return (
        <AllowanceClass classes={classes} />
    )
}

S
Sina

React linter 假设每个以 use 开头的方法作为钩子,并且钩子在类中不起作用。通过将 const useStyles 重命名为不以 use 开头的任何其他名称,例如 const myStyles,您就可以开始了。

更新:

makeStyles 是钩子 api,您不能在类中使用它。您可以使用样式化组件 API。见here


将 usestyles 更改为 mystyles 但仍然发生错误。
是否有任何文件表明这是真的?
你是对的。 makeStyles 是钩子 api,你不能在类中使用它。见here
D
Djafer Abdelhadi

对我来说,错误是在导出的函数默认值之外调用函数 useState


d
double-beep

昨天,我缩短了代码(只是添加了<Provider store={store}>),仍然遇到了这个无效的钩子调用问题。这让我突然意识到自己犯了什么错误:我没有在那个文件夹中安装 react-redux 软件。

我已经在另一个项目文件夹中安装了这个软件,所以我没有意识到这个软件也需要它。安装后,错误消失了。


你怎么修好它的?我也使用提供者游戏控制台报告我有一些关于钩子调用的错误
F
Frank Adeleye

当你错误地从 react-redux 声明 useDispatch 时,也会出现此错误:当你走时:
const dispatch = useDispatch 而不是:
const dispatch = useDispatch(); (即记得添加括号)


对我来说,这与未在项目级别安装的 redux react-redux 软件包有关(但存在于 monorepo 的顶层)。
J
JxDarkAngel

complementing the following comment

对于那些使用 redux 的人:

class AllowanceClass extends Component{
    ...
    render() {
        const classes = this.props.classes;
        ...
    }
}
    
const COMAllowanceClass = (props) =>
{
    const classes = useStyles();
    return (<AllowanceClass classes={classes} {...props} />);
};

const mapStateToProps = ({ InfoReducer }) => ({
    token: InfoReducer.token,
    user: InfoReducer.user,
    error: InfoReducer.error
});
export default connect(mapStateToProps, { actions })(COMAllowanceClass);

G
Gabriel Petersson

我的共享库之间的不同版本的反应似乎是问题(16和17),都改为16。


M
Mohamad ELnomrossie

将此添加到您的 package.json

"peerDependencies": {
   "react": ">=16.8.0",
   "react-dom": ">=16.8.0"
}

来源:https://robkendal.co.uk/blog/2019-12-22-solving-react-hooks-invalid-hook-call-warning


这对我有用!非常感谢
C
Chinmay Pandey

您可以将类组件转换为钩子,但 Material v4 有一个 withStyles HOC。 https://material-ui.com/styles/basics/#higher-order-component-api 使用此 HOC,您可以保持代码不变。


i
ishab acharya

我刚刚开始使用钩子,当我在函数中调用 useEffect 时收到上述警告:

然后我必须将 useEffect 移到函数之外,如下所示:

 const onChangeRetypePassword = async value => {
  await setRePassword(value);
//previously useEffect was here

  };
//useEffect outside of func 

 useEffect(() => {
  if (password !== rePassword) {
  setPasswdMismatch(true);

     } 
  else{
    setPasswdMismatch(false);
 }
}, [rePassword]);

希望对某人有所帮助!


S
Shivam Sharma

就我而言,我在 FlatListrenderItem 属性中传递了组件名称,而不是函数。它在早期工作,因为我的组件是一个功能组件,但是当我在其中添加挂钩时,它失败了。

前:

    <FlatList
        data={memberList}
        renderItem={<MemberItem/>}
        keyExtractor={member => member.name.split(' ').join('')}
        ListEmptyComponent={
          <Text style={{textAlign: 'center', padding: 30}}>
            No Data: Click above button to fetch data
          </Text>
        }
      />

后:

    <FlatList
        data={memberList}
        renderItem={({item, index}) => <MemberItem item={item} key={index} />}
        keyExtractor={member => member.name.split(' ').join('')}
        ListEmptyComponent={
          <Text style={{textAlign: 'center', padding: 30}}>
            No Data: Click above button to fetch data
          </Text>
        }
      />

我遇到了同样的问题,一旦找到解决方案,我就可以找到您的答案。投票提高!
A
AnatuGreen

就我而言,只是我的 App.js 上的这一行代码导致了这种情况,让我在调试中损失了 10 个小时。 React Native 和 Expo 无法指出这一点。我做了 StackOverflow 和 github 上的所有事情,甚至是应该解决这个问题的反应页面,但问题仍然存在。我不得不开始一点一点地拆开我的代码才能找到罪魁祸首

 **const window = useWindowDimensions();**

它是这样放置的:

import * as React from 'react';
import { Text, View, StyleSheet, ImageBackground, StatusBar, Image, Alert, SafeAreaView, Button, TouchableOpacity, useWindowDimensions } from 'react-native';
import Constants from 'expo-constants';

import Whooksplashscreen11 from './Page1';
import Screen1 from './LoginPage';
import Loginscreen from './Login';
import RegisterScreen1 from './register1';
import RegisterScreen2 from './register2-verifnum';
import RegisterScreen3 from './register3';
import RegisterScreen4 from './register4';
import RegisterScreen5 from './register5';
import RegisterScreen6 from './register6';
import BouncyCheckbox from "react-native-bouncy-checkbox";
import LocationPermission from './LocationPermission.js'
import Selfieverif1 from './selfieverif1'
import Selfieverif2 from './selfieverif2'
import AddPhotos from './addphotos'


// You can import from local files
import { useFonts } from 'expo-font';

// or any pure javascript modules available in npm

import { NavigationContainer } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';


//FontAwesome
import { library } from '@fortawesome/fontawesome-svg-core'
import { fab, } from '@fortawesome/free-brands-svg-icons'
import { faCheckSquare, faCoffee, faFilter, faSearch,  } from '@fortawesome/free-solid-svg-icons'
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome'
import Icon  from "react-native-vector-icons/FontAwesome5";

import MyTabs from './swipepage'

library.add(fab, faCheckSquare, faCoffee, faFilter, faSearch,);


const window = useWindowDimensions();
const Stack = createNativeStackNavigator();

function App() {
  return ( ....
)}

F
Forest baba

就我而言,我试图在 Windows 上使用 mdbreact。虽然它已安装,但我收到了上述错误。我不得不重新安装它,一切都很好。曾经两次用 antd Library 发生在我身上


这对我也有帮助,我只是决定完全使用另一个 UI 库
P
Poolio

如果您使用的是 mobx,并且您的功能组件包装在 mobx observer 函数中,也会发生此错误。如果是这种情况,请确保您使用的是 mobx-react 6.0.0 或更高版本。旧版本会将您的功能组件转换为隐藏的类,并且所有挂钩都将因此错误而失败。

在此处查看答案:React Hooks Mobx: invalid hook call. Hooks can only be called inside of the body of a function component


P
PHANTOM-X

在我的情况下,我从两个项目中删除了 package-lock.jsonnode_modules 并再次重新安装,现在工作正常。


// project structure


root project
- package-lock.json
- package.json // all dependencies are installed here
- node_modules

-- second project
-- package-lock.json
-- package.json 
  "dependencies": {
    "react": "file:../node_modules/react",
    "react-dom": "file:../node_modules/react-dom",
    "react-scripts": "file:../node_modules/react-scripts"
  },
-- node_modules


不知道是什么首先导致了这个问题,因为这发生在我之前并且做了与上面相同的步骤,并且问题得到了解决。


O
Orlando G Rodriguez

我遇到了类似的问题,但是我的情况有点极端。

接受的答案应该适用于大多数人,但对于在使用 Radium 的现有反应代码中使用反应钩子的其他任何人,请注意,如果您使用镭,钩子将无法工作,如果没有变通方法。

就我而言,我正在像这样导出我的组件:

// This is pseudocode

const MyComponent = props => {
  const [hookValue, setHookValue] = useState(0);
  return (
    // Use the hook here somehow
  )
}

export default Radium(MyComponent)

export 中删除该 Radium 包装器解决了我的问题。如果您需要使用 Radium,使用类组件及其生命周期函数可能是更简单的解决方案。

希望这至少可以帮助另一个人。


E
Egidius

如果您的前端工作位于其自己的文件夹中,您可能需要在该文件夹中安装 @material-ui/core @material-ui/icons,而不是在后端文件夹中。

npm i @material-ui/core @material-ui/icons


F
Feras

如果上述所有方法都不起作用,特别是如果具有大尺寸依赖性(如我的情况),则构建和加载都需要至少 15 秒,因此延迟似乎给出了错误消息“无效的钩子调用”。所以你可以做的是在测试之前给一些时间来确保构建完成。


P
Pavel Kalashnikov

发现此错误:找到解决方案。

出于某种原因,我的标签上有 2 个 onClick 属性。小心使用您或某人的自定义组件,可能其中一些已经具有 onClick 属性。


S
Salim Nadji

当您使用依赖项而不安装它时也会发生这种情况。当我从“@material-ui/icons/”调用 MenuIcon 时发生在我身上,而该项目中缺少该菜单图标。


D
Dharman

这是为我解决的问题。我的组件文件夹以及它所属的项目的根目录中有文件夹 node_modules 和文件 package.json 和 package-lock.json。我从它们不属于的地方删除了它们。不要问我做了什么把它们放在那里,我一定是从错误的位置做了一个 npm 的东西。


E
Eden Berdugo

就我而言,我在 package-json 中所做的更改会导致问题。

npm install react-redux

解决这个问题


N
Nathan Gilson

如果您使用的是 react-router-dom,请确保在钩子中调用 useHistory()。


R
Rafi Ullah

您可以检查您的路线。如果您在 Route(} />) 中使用渲染而不是组件,那么您在箭头中正确调用了您的组件函数传递适当的道具。


P
Patrik Rikama-Hinnenberg

注意导入问题-对我来说,错误是关于组件和子组件的导入/自动导入失败。与功能类与类组件无关。

这很容易发生,因为 VS 代码自动导入可以指定不起作用的路径。

如果使用 import { MyComponent } 并在组件中使用 export default ,则导入应该说 import MyComponent

如果某些组件在其文件夹中使用 index.js 作为路径的快照,而其他不是导入的组件可能会中断。在这里,自动导入再次可能会导致问题,因为它将所有组件合并到与来自“../../common”的 {TextComponent, ButtonComponent, ListComponent} 相同的文件夹中

尝试注释掉文件中给出错误的一些组件,您可以测试这是否是问题所在。


k
keegan snell

就我而言,问题是我 cd 到了错误的目录来进行我的 npm 安装。我刚刚在正确的目录中重新安装了库,它工作正常!


M
Michael Guild

我在处理自定义 node_module 并使用 npm linkcra(创建反应应用程序)中进行测试时遇到了同样的问题。

我发现在我的自定义 node package 中,我必须添加一个 peerDependencies

"peerDependencies": {
    "@types/react": "^16.8.6 || ^17.0.0",
    "react": "^17.0.0",
    "react-dom": "^17.0.0"
  },

将其添加到我的 package.json 中后,我然后 re-built 我的自定义包。然后在CRA中,我吹走node_modules,重新npm install,重新做npm link <package>,然后启动项目。

修复了一切!


我有同样的情况,但这个解决方案对我不起作用:(
A
Aindriú

我的错误在于最后的导出,我有以下内容:

https://i.stack.imgur.com/fh4TN.png

我应该删除括号:

https://i.stack.imgur.com/yTOfr.png