1

I have a state to keep track when a Sub Menu is opened, and toggle it when another Menu Item is clicked. It goes like this:

    const [open, setOpen] = useState();
    const toggle = (id) => setOpen(id);

    onClick={() => toggle(item.navId)}

So, every time I click on a Menu Item, it closes/opens the Sub Menu. But when I click the browser´s buttons to go to the previous page or the next page, the current opened Sub Menu remains opened and it doesn´t open the Sub Menu that was redirected nor close the current opened Sub Menu. What could I use, just like onClick to change the state, when I navigate through the pages with the previous/next buttons in the browser? Thanks!

BraulioPortela
  • 199
  • 1
  • 10

2 Answers2

1

I found a similar stack post here and I believe someone's answer might help you with a little modification

import React from "react";
import useHistory from "react-router-dom";
import { SubMenu, OtherComponent } from './'; // import your actual components here

export default function YourComponent() {

  const [open, setOpen] = React.useState(false); // toggle submenu
  const [locationKeys, setLocationKeys] = React.useState([]);
  const history = useHistory();

  React.useEffect(() => {
    return history.listen((location) => {
      if (history.action === "PUSH") {
        if (location.key) setLocationKeys([location.key]);
      }

      if (history.action === "POP") {
        if (locationKeys[1] === location.key) {
          setLocationKeys(([_, ...keys]) => keys);

          // Handle forward event
          console.log("forward button");
          setOpen(!open); // toggle submenu
        } else {
          setLocationKeys((keys) => [location.key, ...keys]);

          // Handle back event
          console.log("back button");
          setOpen(!open); // toggle submenu
        }
      }
    });
  }, [locationKeys, history]);

  return (
    <div>
      {open ?? <SubMenu/>}
      // or
      {open ? <SubMenu/> : <OtherComponent/>}
    </div>
  );
}
Mainly Karma
  • 437
  • 2
  • 12
  • I was able to implement this solution. Two things I'd like to address. First, it works quite well, the current SubMenu closes, but when navigating to the previous or next SubMenu, this one doesn't open. And secondly, I had to try this approach on a different version, which worked as I mentioned, because I am currently using react-router-dom v6, which `useHistory` was replaced by `useNavigate`. I tried to implement that with `useNavigate`, but with no success. Any direction on how to implement with v6 of react-router-dom? I tried reading some docs, but I wasn't able to find a solution. Thanks. – BraulioPortela Nov 25 '21 at 13:17
  • Glad I can help! I'll look into useNavigate as well and see if I can further be of an assistance. – Mainly Karma Nov 29 '21 at 15:19
1

If you are using react router, you could use the useLocation hook and useEffect to handle closing the menu on route change

const {pathname} = useLocation();
useEffect(()=>{
  setOpen(//whatever here)
},[pathname])
WebbH
  • 2,379
  • 1
  • 15
  • 26
  • Indeed I am. I will give it a try. Thanks ever so much. – BraulioPortela Nov 23 '21 at 22:20
  • I gave it a go, but still not quite right. I am able to make the menu to close, but the current menu doesn't open, unless I click on it. I believe I have to set something as a parameter for `setOpen()`, but not quite sure what e how. Here is what I was able to come up with: `let location = SidebarData.map((item) => { return ( item.path ) }); location = useLocation(); const link = location.pathname; useEffect(() => { setOpen() }, [link]);` Any suggestion on what I am doing wrong? – BraulioPortela Nov 24 '21 at 10:19