Koushik Saha
Koushik Saha

Reputation: 427

How to close react-burger-menu when link click in a component?

i am working with negomi/react-burger-menu. i want to close my sidebar menu when a link is click not outside or cross button click just link click then my sidebar menu automatically close itself. But problem is my link is under another component , Suppose my component <ShipForMe/> and my link is under <ShipForMe/> like <NavLink to="/dashboard/ship-for-me/my-request/pending">My Request</NavLink>

Sidebar.js

<div className="sidebar-wrap " id="outer-container">
                <div className="dashboard-menu rounded">
                    <ShipForMe/>
                    <MyWallet/>
                    <Profiles/>
                    <div className="sidebar-item ds-item">
                        <div className="sidebar-item__title">
                            <NavLink to="">VIP Center</NavLink>
                        </div>
                    </div>
                </div>
                <div className="dashboard-responsive rounded">
                    <Menu pageWrapId={ "page-wrap" } outerContainerId={ "outer-container" } isOpen={false}>
                            <div id="page-wrap" style={{marginTop: '-25%'}}>
                                <ShipForMe handleUrl={handleUrl}/>
                                <MyWallet/>
                                <Profiles/>
                                <div className="sidebar-item ds-item">
                                    <div className="sidebar-item__title">
                                        <NavLink to="">VIP Center</NavLink>
                                    </div>
                                </div>
                            </div>
                    </Menu>
                </div>
            </div>

ShipForMe.js

<div className="ship-wrap ds-item">
         <div className="sidebar-item">
            <div className="sidebar-item__title">
               Ship for me
            </div>
            <ul className="sidebar-item__lists">
               <li>
                  <NavLink to="/dashboard/ship-for-me/my-request/pending">My Request</NavLink>
               </li>
               <li>
                  <NavLink to="/dashboard/ship-for-me/forwarding-parcel/abroad-to-bd">My Forwarding Parcel</NavLink>
               </li>
            </ul>
         </div>
      </div>

Note: isOpen{flase} is not working, it is only working when link is physical there.

Upvotes: 4

Views: 6407

Answers (3)

Nijoo
Nijoo

Reputation: 265

If nothing works, This is kinda hacky. try this,

const [navigationKey, setNavigationKey] = useState('');
    
const location = useLocation();

useEffect(() => {
    setNavigationKey(loc.pathname);
}, [location]);

In the Menu element, use, key={navigationKey}

<Menu right width={400} key={navigationKey}>

Upvotes: 0

Digestible1010101
Digestible1010101

Reputation: 99

Have spent a lot of time fiddling with problem. One critical part of the solution is to pass the appropriate callback function as a prop to the < Menu > component:

onStateChange={handleStateChange}

where handleStateChange is defined as:

const handleStateChange = (state) => {
  setMenuOpen(state.isOpen);
};

where setMenuOpen is state setter as defined in:

const [isMenuOpen, setIsMenuOpen] = React.useState(false);

you also need a handleCloseMenu function that calls your setter:

const handleCloseMenu = () => {
  setIsMenuOpen(false);
};

you can then pass handleCloseMenu to an onclick of a button in your sidebar / burger menu.

all together you have:

const [isMenuOpen, setIsMenuOpen] = React.useState(false);
const handleCloseMenu = () => {
  setIsMenuOpen(false);
};
const handleStateChange = (state) => {
  setIsMenuOpen(state.isOpen);
};

return (
  <Menu isOpen={isMenuOpen} onStateChange={handleStateChange}>
     ... Link 1
     <button onClick = {()=>handleCloseMenu}/>
     ....
  </Menu>
)

Here is a working sandbox example I found on the github repo:

And here is the github repo. There's an Issue posted about streamlining it further. But once you pass the correct callback, onStateChange={handleStateChange}, you should be good.

Upvotes: 1

ethanlee123
ethanlee123

Reputation: 101

First stack overflow response so, please bear with me. Also, seems like I'm a bit late but hopefully this can help others.

In your Menu component, add: (1) onOpen={handleOpen}, (2) onClose={handleOpen}, and (3) isOpen={isOpen} properties.

  1. onOpen will trigger when the sidebar nav menu is opened and we want it to set isOpen to true
  2. onClose will trigger whenever the user clicks on the cross icon, overlay, or escape key. (Assuming none of these have been disabled/modified)
  3. isOpen controls whether the sidebar nav menu is rendered open (true) or close (false).

In your ShipForMe component add a reference to a function that will set isOpen to false. In my example ShipForMe is SideBarLinks. And the function is closeSideBar

Here is my example:

  const [isOpen, setOpen] = useState(false)

  const handleIsOpen = () => {
    setOpen(!isOpen)
  }

  const closeSideBar = () => {
    setOpen(false)
  }
  <Menu
    isOpen={isOpen}
    onOpen={handleIsOpen}
    onClose={handleIsOpen}
  > 
    <SideBarLinks closeSideBar={closeSideBar} />
  </Menu
const SideBarLinks = ({ closeSideBar }) => {
  return (
    <>
      <NavLink to="/#about" onClick={closeSideBar}>
        About
      </NavLink>
    </>

Please do let me know if this helps and any feedback is appreciated.

Additional info: react version 17.0.1, react-burger-menu version 3.0.6

References: https://www.npmjs.com/package/react-burger-menu

Upvotes: 10

Related Questions