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

IT技术 javascript reactjs react-hooks material-ui
2021-01-12 15:38:04

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

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

  1. 你可能有不匹配的 React 版本和渲染器(例如 React DOM)
  2. 你可能会违反 Hooks 规则
  3. 您可能在同一个应用程序中拥有多个 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;
6个回答

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

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

工作 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;
有一件事想问你,调用setAllowances(data)后,津贴应该有数据了吧?否则,当配额有数据时?
2021-03-15 15:38:04
我有点困惑,在调用 setAllowances(data) 后,我尝试使用 console.log("data",data); 这有 3 条记录,但如果我尝试使用 console.log("allowance",allowances); 这没什么记录。我可以知道为什么吗?您可以在您的代码示例中尝试。
2021-03-17 15:38:04
在作者的允许范围内,他们在哪里调用钩子?
2021-03-21 15:38:04
是的。在调用 setAllowances(data) 之后。setAllowances像工作一样this.setState({allowances: data})
2021-03-23 15:38:04
原因setAllowances是像 this.setState 这样的异步。所以你登录allowancessetAllowances它会记录old allowances.
2021-04-10 15:38:04

我以前npm link安装本地库时遇到了这个问题,我使用cra. 我在这里找到了答案字面意思是:

当您使用 npm link 或等效物时,也会出现此问题。在这种情况下,你的打包器可能会“看到”两个 Reacts——一个在应用程序文件夹中,一个在你的库文件夹中。假设“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,项目目录中的问题已解决。

这对我有用。这是我的确切问题。
2021-03-22 15:38:04
cra长期以来,我一直在使用链接到本地​​库的应用程序,但我从未看到过此错误消息。只需npm i在这两个项目上npm link再次运行就可以了。
2021-03-24 15:38:04
那么在npm上发布的时候会报错吧?或者可能不是,因为它是链接的,在我的机器上,它将使用来自链接的反应,发布后,它将使用自己的。🤔
2021-03-26 15:38:04
我花了 8 个小时解决这个问题,并试图以不同的方式完成该功能。太感谢了
2021-03-27 15:38:04
谢了哥们!你救了我的一天!所有通过 npm/yarn 链接使用本地包的人,请关注这个!
2021-03-29 15:38:04

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

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

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

React linter 假设每个方法都以use钩子开头,而钩子在类中不起作用。通过重命名const useStyles成别的不开始与useconst myStyles你是好去。

更新:

makeStyles是 hook api,您不能在类中使用它。您可以使用样式化组件 API。这里

将 usestyles 更改为 mystyles 但仍然发生错误。
2021-03-22 15:38:04
是否有任何文件表明这是真的?
2021-03-22 15:38:04
是的,你是对的。makeStyles 是 hook api,您不能在类中使用它。这里
2021-04-02 15:38:04

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