Home > Mobile >  How to toggle DropdownMenu when clicking a button in React?
How to toggle DropdownMenu when clicking a button in React?

Time:11-16

I have this DropdownMenu component that works just fine. Basically, if you click on "Click me" button you'll see a DropdownMenu then if you either click outside the DropdownMenu or select an option by clicking on it the Dropdown disappears and this is expected.

My issue is that I want to be able to toggle the Dropdown Menu when clicking on "Click me" button, as of right now if I click on "Click me" button the menu shows up, then if I click again on "Click me" button the DropdownMenu won't go away (I want to toggle it). Can anyone point me in the right direction and tell me what I'm missing or need to do please? Thanks a lot in advance!

Here's a LIVE DEMO of my code, and here are the 2 functions that handle the toggle for my DropdownMenu and handle the ClickOutside.

const handleToggle = () => setOpen((isOpen) => !isOpen);

const handleClickOutside = (evt: MouseEvent) =>
  !menuListRef?.current?.contains(evt.target as HTMLElement) &&
   setOpen(false);

CodePudding user response:

You should define a ref also on your button:

const buttonRef = useRef<HTMLDivElement | null>() as React.MutableRefObject<HTMLInputElement>;

...

<StyledMenuButton onClick={handleToggle} ref={buttonRef}>

And add a check for it not to be the clicked element in handleClickOutside:

const handleClickOutside = (evt: MouseEvent) => {
  if (!menuListRef?.current?.contains(evt.target as HTMLElement) &&
  !buttonRef?.current?.contains(evt.target as HTMLElement)) {
    setOpen(false);
  }
}

Working sandbox.

CodePudding user response:

const buttonRef = useRef<HTMLDivElement | null>() as React.MutableRefObject<HTMLInputElement>;
.
.
.
const handleClickOutside = (evt: MouseEvent) => {
  const dropdownClicked = menuListRef?.current?.contains(
    evt.target as HTMLElement
  );
  const buttonToOpenClicked = buttonRef?.current?.contains(
    evt.target as HTMLElement
  );
  // If nether the button or dropdown menu has been clicked
  // You haven't clicked "outside"
  if (!dropdownClicked && !buttonToOpenClicked) {
    console.log("Clicked outside");
    setOpen(false);
  }
};
.
.
.
<StyledMenuButton onClick={handleToggle} ref={buttonRef}>
  • Related