DEV Community

loading...

Ionic Horizontal & SideMenu Navigation in ReactJS

Aaron K Saunders
See more, like and subscribe 👉🏾 ‪Aaron Saunders 📺 https://www.youtube.com/aaronsaundersci?sub_confirmation=1
・2 min read

Alt Text

The Magic..

We listed for this event, MediaQueryListEvent and we get an object that looks something like this back.

MediaQueryListEvent : {
  isTrusted: true, 
  media: "(min-width: 768px)", 
  matches: true,
  ...
}

We are looking to see if we get a match from the query and if so, then we want to take action.

Let's set up our state variable mQuery using useState and initialized it by getting the current window innerWidth.

const [mQuery, setMQuery] = React.useState<any>({
  matches: window.innerWidth > 768 ? true : false,
});

In our component we will listen for this event, from the window object by calling window.matchMedia

  useEffect(() => {
    let mediaQuery = window.matchMedia("(min-width: 768px)");
    mediaQuery.addListener(setMQuery);

    // this is the cleanup function to remove the listener
    return () => mediaQuery.removeListener(setMQuery);
  }, []);

the addListener calls our setState function to hold the results, and the changing of the state variable will cause the component to rerender.

Based on the state variable we will render the hamburger menu or the list of buttons that correspond to the side menu items

Full source for NavButtons component

// NavButtons.tsx
export const NavButtons = () => {
const [mQuery, setMQuery] = React.useState<any>({
  matches: window.innerWidth > 768 ? true : false,
});

  useEffect(() => {
    let mediaQuery = window.matchMedia("(min-width: 768px)");
    mediaQuery.addListener(setMQuery);

    // this is the cleanup function to remove the listener
    return () => mediaQuery.removeListener(setMQuery);
  }, []);

  // MediaQueryListEvent { isTrusted: true, media: "(min-width: 768px)", matches: true ...}

  return (
    <div>
      {mQuery && !mQuery.matches ? (
        <IonMenuButton />
      ) : (
        <>
          <IonButton routerLink={"/home"}>Home </IonButton>
          <IonButton routerLink={"/page-1"}>One </IonButton>
          <IonButton routerLink={"/page-2"}>Two</IonButton>
        </>
      )}
    </div>
  );
};

Then we use the component in the IonToolbar of our pages, see an example below

// Home.tsx
const Home: React.FC = () => {
  return (
    <IonPage>
      <IonHeader>
        <IonToolbar>
          <IonTitle>HOME</IonTitle>
          <IonButtons slot="end">
            <NavButtons/> // <== OUR COMPONENT
          </IonButtons>
        </IonToolbar>
      </IonHeader>
      <IonContent fullscreen>
      </IonContent>
    </IonPage>
  );
};

export default Home;

Full Source Code for the Project In GitHub

GitHub logo aaronksaunders / sidemenu-topnav-ionic-react

Ionic Horizontal & SideMenu Navigation in ReactJS

Discussion (1)

Collapse
aaronksaunders profile image
Aaron K Saunders Author

Added the cleanup function to remove the listener

  useEffect(() => {
    let mediaQuery = window.matchMedia("(min-width: 768px)");
    mediaQuery.addListener(setMQuery);

    // this is the cleanup function to remove the listener
    return () => mediaQuery.removeListener(setMQuery);
  }, []);