Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

multiple dropdown state and handling outside click in React

I have a parent component that holds multiple Dropdown child components. The state is managed within the parent component to show only one dropdown at a time. I currently have part of it working but am having some trouble wrapping my head around the logic to make it so that when you click outside of a dropdown if its open then it will close the dropdown. I have tried using useRef hook to detect click outside, but still having trouble wrapping my head around the logic to make things display correctly.

const MultipleDropdownPage = () => {
    const [dropdown, setDropdown] = useState(null);
    const handleDropdown = id => {
        if (dropdown === id) {
            setDropdown(null);
        }
        if (dropdown !== id) {
            setDropdown(id);
        }
    };
    return (
        <div>
            {dropdown ? dropdown : 'Nothing'}
            <Dropdown handleDropdown={handleDropdown} dropdown={dropdown} id='1' />
            <Dropdown handleDropdown={handleDropdown} dropdown={dropdown} id='2' />
        </div>
    );
};
import React from 'react';

const Dropdown = ({ handleDropdown, id, dropdown }) => {
    return (
        <div>
            <button onClick={() => handleDropdown(id)}>Click me</button>
            {id === dropdown && (
                <div className='dropdown'>
                    <ul>
                        <li>Lorem, ipsum.</li>
                        <li>Dolore, eligendi.</li>
                        <li>Quam, itaque!</li>
                    </ul>
                </div>
            )}
        </div>
    );
};

export default Dropdown;

like image 216
ewcoder Avatar asked Oct 16 '25 04:10

ewcoder


1 Answers

Needed to set a class on the button itself and then check if when the document is clicked it doesn't match that button class

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

const Dropdown = ({ handleDropdown, id, dropdown }) => {
    const ref = useRef();
    useEffect(() => {
        const handleClick = e => {
            if (!e.target.classList.contains('dropdown-toggle')) {
                handleDropdown(null);
            }
        };
        document.addEventListener('click', handleClick);
        return () => document.removeEventListener('click', handleClick);
    }, [handleDropdown]);
    return (
        <>
            <button
                onClick={() => handleDropdown(id)}
                ref={ref}
                className='dropdown-toggle'
            >
                Click me
            </button>
            {id === dropdown && (
                <div className='dropdown'>
                    <ul>
                        <li>Lorem, ipsum.</li>
                        <li>Dolore, eligendi.</li>
                        <li>Quam, itaque!</li>
                    </ul>
                </div>
            )}
        </>
    );
};

export default Dropdown;

like image 87
ewcoder Avatar answered Oct 17 '25 16:10

ewcoder



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!