簡體   English   中英

如何在 React 上使用 Material Ui。 收到錯誤無效的掛鈎調用

[英]How to use Material Ui on React. getting error Invalid Hook call

`× 錯誤:無效的鈎子調用。 鈎子只能在 function 組件的主體內部調用。 這可能由於以下原因之一而發生:

  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>
  );
}
}

makeStyles返回一個鈎子,即 useStyles。 您只能在功能組件中使用鈎子。

  1. 一種選擇是將 class 組件轉換為功能組件。 還要確保將 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. 另一種選擇是保持基於 class 的組件完整並使用 withStyles。

請參閱withStyles API 文檔

如果您需要訪問主題,請使用 function 簽名。 它作為第一個參數提供。

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);

好吧,這幾乎就是錯誤所說的。 鈎子只能與功能組件一起使用。 EventsList是一個 class 組件,您正在嘗試在其中使用makeStyles

我遇到了同樣的問題,但我注意到終端顯示“編譯成功”消息,但瀏覽器仍然給我這個錯誤。

  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目錄中。希望一切都會得到修復。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM