Home > Software design >  What's the best way to call a hook function on click in React
What's the best way to call a hook function on click in React

Time:04-22

I was creating some header for my app, so I tried to place the hooks in some other file for better organization.

But I'm a bit confused, how do I call this function useHeaderNavStatus() when I click the button in the header tag, without creating another useEffect and useState in Header component? Is it possible or I'm too blind?

I appreciate any help! :D

Here is the file structure:

enter image description here

Header Component

const Header = () => {
    const headerNav = useHeaderNavStatus();

    return (
      <header>
        <button
        ref={headerNav.toggleRef}
        onClick={What do I do here?}>
          Menu
        </button>
      </header>
    );
}

Hooks file

import { useEffect, useRef, useState } from 'react';

const useHeaderNavStatus = () => {
    // Creating ref for toggle button
    const toggleRef = useRef<HTMLButtonElement>(null);

    // Creating state to know if nav is showing or not
    const [isActive, setIsActive] = useState(false);

    // This function opens and closes nav
    const updateBodyScroll = () => {
        setIsActive(!isActive);
        const body = document.body.classList;

        if (isActive) {
            body.remove('no-scroll');
        } else {
            body.add('no-scroll');
        }
    };

    // This function closes the nav on outside click
    const closeNavOnOutsideClick = (event: MouseEvent) => {
        if (!toggleRef.current?.contains(event.target as Node))
            updateBodyScroll();
    };

    // Adds and removes event listener to know the target click
    useEffect(() => {
        if (isActive) {
            window.addEventListener('mousedown', closeNavOnOutsideClick);

            return () =>
                window.removeEventListener('mousedown', closeNavOnOutsideClick);
        }
    });

    return { toggleRef, isActive };
};

CodePudding user response:

Your hook should also return a function that opens the nav:

const openNav = () => setIsActive(true);

return { toggleRef, isActive, openNav };

And then use it:

const Header = () => {
    const headerNav = useHeaderNavStatus();

    return (
      <header>
        <button
        ref={headerNav.toggleRef}
        onClick={headerNav.openNav}>
          Menu
        </button>
      </header>
    );
}
  • Related