错误:无效的挂钩调用。挂钩只能在功能组件的主体内部调用。在使用React.js时

时间:2019-12-13 11:14:02

标签: javascript reactjs

我遇到错误:

  

错误:无效的挂接调用。挂钩只能在功能组件的主体内部调用。

我的挂钩代码:

function WidthAndHeight() {
  const [width, setWidth] = React.useState(window.innerWidth);
  const [height, setHeight] = React.useState(window.innerHeight);

  React.useEffect(() => {
    window.addEventListener("resize", updateWidthAndHeight);
    return () => window.removeEventListener("resize", updateWidthAndHeight);
  });

  const updateWidthAndHeight = () => {
    setWidth(window.innerWidth);
    setHeight(window.innerHeight);
  };

  return (
    {
      "width": width,
      "height": height
    }
  );
}

当我在onMouseEnter上调用它时,出现以下错误:

class MegaMenu extends React.Component {
  public render() {
    return (
      <div className={styles.MegaMenu}>
        <div className={styles["menu-container"]}>
          <div className={styles.menu}>
            <MenuList Options={menus} />
          </div>
        </div>
      </div>
    )
  }
}

const MenuList = (props: IMenuListProps) => {
  const handleOnMouseEnter = () => {
    if (WidthAndHeight().width > 943) {
      console.log("WidthAndHeight().width")
    }
  }

  return (
    <ul onMouseEnter={handleOnMouseEnter}>
      {
        props.Options.map((Option: IMenu, index: number) => (
          <li key={index} className={(Option.subitem && Option.subitem.length > 0) ? styles["menu-dropdown-icon"] : styles["normal-sub"]} onMouseEnter={handleOnMouseEnter}>
            <a href={Option.link}>{Option.name}</a>
            {/* Base Case */}
            {
              (Option.subitem && Option.subitem.length > 0) &&
              <MenuList Options={Option.subitem} />
            }
          </li>
        ))
      }
    </ul>
  )
}

有人可以指导我如何解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

您已经创建了自定义钩子,但是使用错误。下面的代码应该可以工作。

const MenuList = (props: IMenuListProps) => {
  const { width, height } = WidthAndHeight(); // --> call hook in component function body, not in eventhandler!
  const handleOnMouseEnter = () => {
    if (width > 943) {
      //...
    }
  }

  return (
    <ul onMouseEnter={handleOnMouseEnter}>
      {
        props.Options.map((Option: IMenu, index: number) => (
          <li key={index} className={(Option.subitem && Option.subitem.length > 0) ? styles["menu-dropdown-icon"] : styles["normal-sub"]} onMouseEnter={handleOnMouseEnter}>
            <a href={Option.link}>{Option.name}</a>
            {/* Base Case */}
            {
              (Option.subitem && Option.subitem.length > 0) &&
              <MenuList Options={Option.subitem} />
            }
          </li>
        ))
      }
    </ul>
  )
}

答案 1 :(得分:0)

您需要使用自定义钩子进行操作-

function useWidthAndHeight() {
  const [width, setWidth] = React.useState(window.innerWidth);
  const [height, setHeight] = React.useState(window.innerHeight);

  React.useEffect(() => {
    window.addEventListener("resize", updateWidthAndHeight);
    return () => window.removeEventListener("resize", updateWidthAndHeight);
  });

  const updateWidthAndHeight = () => {
    setWidth(window.innerWidth);
    setHeight(window.innerHeight);
  };

 const windowData =  {
      "width": width,
      "height": height
    }
  return (
   windowData
  );
}

export default function useWidthAndHeight

然后您可以像这样导入它。

import useWidthAndWIndow from "./customHook.js"

并将其用作功能组件内部的挂钩

const windowData = useWidthAndWIndow()