DEV Community

Aaron K Saunders
Aaron K Saunders

Posted on

Ionic Horizontal & SideMenu Navigation in ReactJS

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,
  ...
}
Enter fullscreen mode Exit fullscreen mode

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,
});
Enter fullscreen mode Exit fullscreen mode

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);
  }, []);
Enter fullscreen mode Exit fullscreen mode

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>
  );
};
Enter fullscreen mode Exit fullscreen mode

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;
Enter fullscreen mode Exit fullscreen mode

Full Source Code for the Project In GitHub

GitHub logo aaronksaunders / sidemenu-topnav-ionic-react

Ionic Horizontal & SideMenu Navigation in ReactJS






Top comments (2)

Collapse
 
aaronksaunders profile image
Aaron K Saunders

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);
  }, []);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
lsh profile image
Lavanya

hey @aaronksaunders can you plz tell me whether you wrote this code in separate js file or in App.js file?