最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - React Dropdown Menu Doesn't Toggle Properly on Click - Stack Overflow

programmeradmin1浏览0评论

I have a Navbar component with an "Account" button that should toggle a dropdown menu. The dropdown should open when clicked and close when clicking outside or clicking the button again. However, clicking "My Account" only opens the menu but doesn't close it when clicked again.

Navbar.jsx

import { useState } from 'react';
import { Link } from 'react-router-dom';
import AccountDropdown from '../AccountDropdown';

const Navbar = () => {
  const [isAccountMenuOpen, setIsAccountMenuOpen] = useState(false);

  const toggleAccountMenu = (event) => {
    event.stopPropagation();
    setIsAccountMenuOpen((prev) => !prev);
  };

  const handleAccountMenuClose = () => {
    if (isAccountMenuOpen) setIsAccountMenuOpen(false);
  };

  return (
    <nav>
      <button onClick={toggleAccountMenu}>My Account</button>
      {isAccountMenuOpen && <AccountDropdown onClose={handleAccountMenuClose} />}
    </nav>
  );
};

export default Navbar;

AccountDropdown.jsx

import { useEffect, useRef } from 'react';

const AccountDropdown = ({ onClose }) => {
  const dropdownRef = useRef(null);

  useEffect(() => {
    const handleClickOutside = (event) => {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
        onClose();
      }
    };

    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, [onClose]);

  return (
    <div ref={dropdownRef}>
      <button onClick={onClose}>Close</button>
      <a href="/profile">Profile</a>
      <a href="/logout">Log Out</a>
    </div>
  );
};

export default AccountDropdown;

Clicking "My Account" always opens the menu, but clicking it again doesn't close it. How can I properly toggle the dropdown?

I have a Navbar component with an "Account" button that should toggle a dropdown menu. The dropdown should open when clicked and close when clicking outside or clicking the button again. However, clicking "My Account" only opens the menu but doesn't close it when clicked again.

Navbar.jsx

import { useState } from 'react';
import { Link } from 'react-router-dom';
import AccountDropdown from '../AccountDropdown';

const Navbar = () => {
  const [isAccountMenuOpen, setIsAccountMenuOpen] = useState(false);

  const toggleAccountMenu = (event) => {
    event.stopPropagation();
    setIsAccountMenuOpen((prev) => !prev);
  };

  const handleAccountMenuClose = () => {
    if (isAccountMenuOpen) setIsAccountMenuOpen(false);
  };

  return (
    <nav>
      <button onClick={toggleAccountMenu}>My Account</button>
      {isAccountMenuOpen && <AccountDropdown onClose={handleAccountMenuClose} />}
    </nav>
  );
};

export default Navbar;

AccountDropdown.jsx

import { useEffect, useRef } from 'react';

const AccountDropdown = ({ onClose }) => {
  const dropdownRef = useRef(null);

  useEffect(() => {
    const handleClickOutside = (event) => {
      if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
        onClose();
      }
    };

    document.addEventListener('mousedown', handleClickOutside);
    return () => document.removeEventListener('mousedown', handleClickOutside);
  }, [onClose]);

  return (
    <div ref={dropdownRef}>
      <button onClick={onClose}>Close</button>
      <a href="/profile">Profile</a>
      <a href="/logout">Log Out</a>
    </div>
  );
};

export default AccountDropdown;

Clicking "My Account" always opens the menu, but clicking it again doesn't close it. How can I properly toggle the dropdown?

Share Improve this question asked Feb 4 at 8:10 in43shin43sh 9432 gold badges14 silver badges37 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 1

Verify that your onClick handler correctly toggles the state. For example, using useState:

const [isOpen, setIsOpen] = useState(false);
const toggleDropdown = (e) => {
  e.stopPropagation(); // Prevents event bubbling
  setIsOpen((prev) => !prev);
};

Because you are using ref to close dropdown while clicking outside of the dropdown content. So once the dropdown is opened "My account" button also considered as a ouside click, it won't match with the outer click function which is you called. That's why dropdown closed and reopened when you click "My account" button.

So for your simple case, just modify either one:

const toggleAccountMenu = (event) => {
    if(isAccountMenuOpen) return;
    setIsAccountMenuOpen(true);
  };

Or second case:

   <nav>
      <button style={{ pointerEvents: isAccountMenuOpen ? 'none' : 'all' }}
      onClick={toggleAccountMenu}>My Account</button>
      {isAccountMenuOpen && <AccountDropdown onClose={handleAccountMenuClose} 
      />}
    </nav>
发布评论

评论列表(0)

  1. 暂无评论