使用挂钩管理菜单的显示/隐藏

时间:2020-06-12 16:42:24

标签: reactjs react-hooks

在管理菜单的显示/隐藏方面,我很难让钩子起作用。我的理解是,正确的方法是创建一个在组件之间共享的自定义钩子。

我已经创建了自定义钩子,并将其导入到相关的组件中,但是这些组件似乎对状态变化没有反应(即,单击打开或关闭按钮无效)。

我创建了一个最小的代码示例:https://codesandbox.io/s/nostalgic-taussig-67qvp

1 个答案:

答案 0 :(得分:1)

当然,由于自定义钩子不能在组件之间共享,因此您的代码将无法工作,您需要使用上下文api或某些全局状态管理器(例如redux)来实现,或者可以通过以下方式将prop传递给孩子:

父组件:

import React,{useState,useEffect} from "react";
import MenuButton from "./MenuButton";
import MobileMenu from "./MobileMenu";
//import MobileMenu from "./menus/MobileMenu";
export default function Foobar() {
  const [isOpen,setIsOpen] = useState(false)
  const toggle = ()=>setIsOpen(current=>!current)
  return (
    <div>
      <MenuButton click={toggle} />
      <MobileMenu isOpen={isOpen} click={toggle} />
    </div>
  );
}

这里将通过传递状态作为道具来设置两个孩子的共享状态,并且从其孩子可以访问装备功能。

对于菜单按钮组件:

import React from "react";

export default function MenuButton({click}) {
  return (
    <div id="menu-button-div" className="-mr-2 flex items-center md:hidden">
      <button
        type="button"
        onClick={click}
        className="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 focus:text-gray-500 transition duration-150 ease-in-out"
        id="main-menu"
        aria-label="Main menu"
        aria-haspopup="true"
      >
        <svg
          className="h-6 w-6"
          stroke="currentColor"
          fill="none"
          viewBox="0 0 24 24"
        >
          <path
            strokeLinecap="round"
            strokeLinejoin="round"
            strokeWidth={2}
            d="M4 6h16M4 12h16M4 18h16"
          />
        </svg>
        OPEN
      </button>
    </div>
  );
}

在这里,点击道具会在父级中触发切换功能,从而切换状态isOpen

,然后选择“组件”菜单

import React  from "react";
import "./styles.css";
export default function MobileMenu({isOpen,click}) {
  return (
    <div id="mobile-menu-div" className={isOpen?"":"hidden"}>
      menu content
      <button
        type="button"
        onClick={click}
        className="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 focus:text-gray-500 transition duration-150 ease-in-out"
        aria-label="Close menu"
      >
        <svg
          className="h-6 w-6"
          stroke="currentColor"
          fill="none"
          viewBox="0 0 24 24"
        >
          <path
            strokeLinecap="round"
            strokeLinejoin="round"
            strokeWidth={2}
            d="M6 18L18 6M6 6l12 12"
          />
        </svg>
        CLOSE
      </button>
    </div>
  );
}

现在,菜单组件将可以访问作为prop传递的父状态isOpen 并且您无需使用useEffect来切换javascript行中的jsx类支持。 很好,您不需要自定义钩子即可实现这一目标,希望这是您想要的。

正常工作的example.