This solution is generated by ChatGPT, correctness is not guaranteed. You might also be able to find a solution fromcommunity posts.
AI solution for React Coding Question on BFE.dev
15. useClickOutside()
To implement the useClickOutside()
hook, we need to:
- Define a ref using the
useRef()
hook to store a reference to the element that we want to detect clicks outside of. - Define a callback function that runs when a click event is detected outside the element that we are tracking.
- Add event listeners to detect clicks on the document once the component has been mounted using the
useEffect()
hook. - Remove event listeners when the component is unmounted using the cleanup function returned from
useEffect()
.
Here is one possible implementation of the useClickOutside()
hook:
import { useRef, useEffect } from 'react';function useClickOutside(onClickOutside) { const ref = useRef(null); useEffect(() => { const handleClickOutside = (event) => { if (ref.current && !ref.current.contains(event.target)) { onClickOutside(); } }; document.addEventListener('mousedown', handleClickOutside); return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, [ref, onClickOutside]); return ref;}export default useClickOutside;
Then, we can use the useClickOutside()
hook like this:
import { useState } from 'react';import useClickOutside from './useClickOutside';function Component() { const [isMenuOpen, setIsMenuOpen] = useState(false); const toggleMenu = () => { setIsMenuOpen((prevState) => !prevState); }; const closeMenu = () => { setIsMenuOpen(false); }; const menuRef = useClickOutside(closeMenu); return ( <div> <button onClick={toggleMenu}>Toggle Menu</button> {isMenuOpen && ( <ul ref={menuRef}> <li>Menu Item 1</li> <li>Menu Item 2</li> <li>Menu Item 3</li> </ul> )} </div> );}export default Component;
In this example, clicking the "Toggle Menu" button will show/hide a dropdown menu. When the menu is shown, the useClickOutside()
hook is used to detect clicks outside the dropdown menu and close the menu accordingly.