I am coding a FlyoutManager from which I can toggle every flyout menus in react app. I am trying to set the property to close when clicking outside. I found on another stackoverflow question that my clicking-outside function is triggered when I click the button to close it so it re-opens the flyout menu because it toggles the menu state twice.
Have you got some ideas to fix my problem ?
Here is the Header code simplified to my problem :
export const Header = () => {
const {toggleFlyout} = useFlyout();
return (
<header>
<div>
/*
...
Other components
*/
<nav>
/*
...
Other buttons
*/
<button id="UserFlyout" onClick={() => toggleFlyout("UserFlyout")}>
User-logo
</button>
</nav>
</div>
</header>
);
};
Here is the FlyoutContext Folder which contains the toggle function :
export const FlyoutContext = createContext();
export const FlyoutProvider = ({children}) => {
const [flyout, setFlyout] = useState(null);
const [isOpen, setIsOpen] = useState(false)
const toggleFlyout = name => {
setIsOpen(!isOpen);
if (!isOpen) {
setFlyout(name);
} else {
setFlyout(null);
}
}
return (
<FlyoutContext.Provider value={{flyout, toggleFlyout}}>
{children}
</FlyoutContext.Provider>
);
};
export const useFlyout = () => useContext(FlyoutContext);
Here is the FlyoutManager Folder
const FlyoutList = {
UserFlyout: UserFlyout
};
export const FlyoutManager = () => {
const {flyout, toggleFlyout} = useFlyout();
const flyoutRef = useRef(null);
const Flyout = FlyoutList[flyout];
useEffect(() => {
const handler = event => {
if (flyoutRef.current !== null && !flyoutRef.current.contains(event.target)) {
toggleFlyout(flyout);
}
};
document.addEventListener('mousedown', handler);
return () => {
document.removeEventListener('mousedown', handler);
};
}, [flyoutRef, flyout, toggleFlyout]);
if (!flyout) return null;
return (
<Flyout flyoutRef={flyoutRef}>
<div ref={flyoutRef}>
user flyout
</div>
</Flyout>
);
};
Thanks a lot for your help
Some ideas might be to check if the mousedown event target is not the button. But because I use a context I can’t access the id button in the FlyoutContext.