我想用React在一个表中显示一些记录,但我得到了这个错误:

无效的钩子调用。类的主体内部只能调用钩子 功能组件。这可能发生在以下情况之一 原因: React和渲染器的版本可能不匹配(比如React DOM) 你可能违反了胡克斯的规矩 你可能在同一个应用程序中有多个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;

当前回答

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

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

其他回答

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

这很容易发生,因为VS code自动导入可以指定的路径不能工作。 如果在组件中使用了import {MyComponent}和export default,则导入应该说import MyComponent 如果某些组件在其文件夹中使用index.js作为路径的shotcut,而其他组件则不使用,则导入可能会中断。在这里,自动导入可能会导致问题,因为它合并了来自'../../common'的{TextComponent, ButtonComponent, ListComponent}相同文件夹中的所有组件

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

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

React Hooks Mobx:无效的钩子调用。钩子只能在函数组件的内部调用

当我链接本地图书馆时,我得到了这个错误。下面的方法解决了我的问题。

在图书馆:

从依赖中删除“react”和“react-dom”,并将它们添加到peerDependencies中。 安装依赖项,构建

重新启动主项目。

你只能从React函数中调用钩子。点击这里阅读更多。

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

Working CodeSandbox演示。

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;

在我的例子中,我在FlatList的renderItem道具中传递组件名称,而不是函数。它在早期工作,因为我的组件是一个功能组件,但当我添加钩子时,它失败了。

之前:

    <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>
        }
      />