【问题标题】:How to use Material Ui on React. getting error Invalid Hook call如何在 React 上使用 Material Ui。收到错误无效的挂钩调用
【发布时间】:2020-11-11 22:05:56
【问题描述】:

`× 错误:无效的挂钩调用。 Hooks 只能在函数组件的主体内部调用。这可能是由于以下原因之一:

  1. 您可能有不匹配的 React 版本和渲染器(例如 React DOM)
  2. 您可能违反了 Hooks 规则
  3. 您可能在同一个应用中拥有多个 React 副本`

我是 React 的新手,我的代码运行良好,但我今天决定使用 MaterialUi,现在它给了我错误,我尝试使用谷歌搜索,但没有成功。另一件事是我的this.state.events 正在返回一个空数组,而不是events 的列表。我该如何解决? 我的 React-dom 版本是 ─ react-dom@16.13.1 而 React 版本是 ─ react@16.13.1

 import React, { Component } from "react";
 import { Link } from "react-router-dom";
 import axios from "axios";

 import { makeStyles } from "@material-ui/core/styles";
 import GridList from "@material-ui/core/GridList";
 import GridListTile from "@material-ui/core/GridListTile";
 import GridListTileBar from "@material-ui/core/GridListTileBar";
 import ListSubheader from "@material-ui/core/ListSubheader";
 import IconButton from "@material-ui/core/IconButton";






  export default class EventsList extends Component {
     constructor(props) {
        super(props);
       this.state = { events: [] };
    }

  componentDidMount() {
    axios
     .get("http://localhost:9000/events/")
     .then((response) => {
      this.setState({ events: response.data });
    })
     .catch(function (error) {
      console.log(error);
    });
  }


 render() {
   const useStyles = makeStyles((theme) => ({
     root: {
       display: "flex",
       flexWrap: "wrap",
       justifyContent: "space-around",
       overflow: "hidden",
       backgroundColor: theme.palette.background.paper,
      },
      gridList: {
       width: 500,
       height: 450,
     },
     icon: {
      color: "rgba(255, 255, 255, 0.54)",
     },
   }));

   const classes = useStyles();

    return (
      <div className={classes.root}>
      <GridList cellHeight={180} className={classes.gridList}>
       <GridListTile key="Subheader" cols={2} style={{ height: "auto" }}>
         <ListSubheader component="div">December</ListSubheader>
        </GridListTile>
        {this.state.events.map((tile) => (
          <GridListTile key={tile.img}>
            <img src={tile.img} alt={tile.title} />
            <GridListTileBar
              title={tile.title}
              subtitle={<span>by: {tile.author}</span>}
              actionIcon={
                <IconButton
                  aria-label={`info about ${tile.title}`}
                  className={classes.icon}
                ></IconButton>
              }
            />
          </GridListTile>
        ))}
      </GridList>
    </div>
  );
}
}

【问题讨论】:

    标签: node.js reactjs material-ui


    【解决方案1】:

    我遇到了同样的问题,但我注意到终端显示“编译成功”消息,但浏览器仍然给我这个错误。

    1. 我实际上将 material-ui/icons 安装为: sudo npm install -g @material-ui/icons (我以为我会以管理员身份在全局范围内安装它,这样我就不必每次都在不同的项目/反应应用程序上安装 material-ui)

    2. 在我正在工作的 react 应用程序中,我刚刚运行 ( npm install @material-ui/icons ) 更新了我的 react 应用程序中的 node_modules 文件夹,错误消失了,浏览器上的一切也正常。

    3. 解决方案:只需在终端上运行“npm install @material-ui/core”和“npm install @material-ui/icons”,位于您正在工作的react app目录中。希望一切都会得到修复.

    【讨论】:

    • 这里也一样,这是一个非常基本但我们搞砸了:)
    【解决方案2】:

    makeStyles 返回一个钩子,即 useStyles。您只能在功能组件中使用钩子。

    1. 一种选择是将您的类组件转换为函数式组件。还要确保将 makeStyles 代码放在组件之外(您不想在每次重新渲染时都执行它)
    import React, { useEffect, useState } from "react";
    // other imports
    
    const useStyles = makeStyles((theme) => ({
      root: {
        display: "flex",
        flexWrap: "wrap",
        justifyContent: "space-around",
        overflow: "hidden",
        backgroundColor: theme.palette.background.paper,
      },
      gridList: {
        width: 500,
        height: 450,
      },
      icon: {
        color: "rgba(255, 255, 255, 0.54)",
      },
    }));
    
    const EventsList = () => {
      const [events, setEvents] = useState([]);
      const classes = useStyles();
      useEffect(() => {
        axios
          .get("http://localhost:9000/events/")
          .then((response) => {
            this.setState({ events: response.data });
          })
          .catch(function (error) {
            console.log(error);
          });
      }, []);
    
      return (
        <div className={classes.root}>
          // rest of code...
        </div>
      );
    };
    
    1. 另一种选择是保持基于类的组件不变并使用 withStyles。

    withStyles API doc:

    如果您需要访问主题,请使用函数签名。它作为第一个参数提供。

    import { withStyles } from "@material-ui/core";
    
    const styles = (theme) => ({
      root: {
        display: "flex",
        flexWrap: "wrap",
        justifyContent: "space-around",
        overflow: "hidden",
        backgroundColor: theme.palette.background.paper,
      },
      gridList: {
        width: 500,
        height: 450,
      },
      icon: {
        color: "rgba(255, 255, 255, 0.54)",
      },
    });
    
    class EventsList extends Component {
      constructor(props) {
        super(props);
        this.state = { events: [] };
      }
    
      componentDidMount() {
        axios
          .get("http://localhost:9000/events/")
          .then((response) => {
            this.setState({ events: response.data });
          })
          .catch(function (error) {
            console.log(error);
          });
      }
    
      render() {
        return (
          <div className={classes.root}>
            <GridList cellHeight={180} className={classes.gridList}>
              <GridListTile key="Subheader" cols={2} style={{ height: "auto" }}>
                <ListSubheader component="div">December</ListSubheader>
              </GridListTile>
              {this.state.events.map((tile) => (
                <GridListTile key={tile.img}>
                  <img src={tile.img} alt={tile.title} />
                  <GridListTileBar
                    title={tile.title}
                    subtitle={<span>by: {tile.author}</span>}
                    actionIcon={
                      <IconButton
                        aria-label={`info about ${tile.title}`}
                        className={classes.icon}
                      ></IconButton>
                    }
                  />
                </GridListTile>
              ))}
            </GridList>
          </div>
        );
      }
    }
    
    export default withStyles(styles)(EventsList);
    

    【讨论】:

      【解决方案3】:

      嗯,这几乎就是错误所说的。钩子只能与功能组件一起使用。 EventsList 是一个类组件,您正在尝试在其中使用 makeStyles

      【讨论】:

        猜你喜欢
        • 2020-03-17
        • 2022-09-30
        • 2021-08-04
        • 1970-01-01
        • 2020-10-03
        • 2021-09-10
        • 1970-01-01
        • 2023-01-04
        • 1970-01-01
        相关资源
        最近更新 更多