Reputation: 1545
I am having a little trouble getting hooks to work in terms of managing the display/hide of a menu. My understanding is that the correct way to do this is to create a custom hook which is shared between components.
I have created my custom hook, and imported it on the relevant components, however the components do not seem to be reacting to a change in state (i.e. clicking on the open or close buttons has no effect).
I have created a minimal code example: https://codesandbox.io/s/nostalgic-taussig-67qvp
Upvotes: 0
Views: 686
Reputation: 3507
of course your code will not work because custom hook are not shareable between component, you need to use context api or some global state manager like redux to achieve or you can do with passing props to the child like this:
parent Component :
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>
);
}
here will are setting shared state to both child by passing the state as props and the toogle function will be accessible from the it'S child.
for the menu Button Component :
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>
);
}
here the click props will fire the toggle function in the parent which will toggle state isOpen
.
and for the menu Component:
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>
);
}
now the menu component will have access to the parent state isOpen
passed as prop
and you don't need to use useEffect
to toggle the class jsx support in line javascript.
well this it and you don't need custom hook to achieve this, hope this what your are looking for.
full working example.
Upvotes: 1