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
aaronksaunders / sidemenu-topnav-ionic-react
Ionic Horizontal & SideMenu Navigation in ReactJS
Ionic Horizontal & SideMenu Navigation in ReactJS
See full explanation and blog post on dev.to
https://dev.to/aaronksaunders/ionic-horizontal-sidemenu-navigation-in-reactjs-2ko6
Ionic Framework Horizontal & SideMenu Navigation in ReactJS Application https://youtu.be/S7whj93SGsA via @youtube
Top comments (2)
Added the cleanup function to remove the listener
hey @aaronksaunders can you plz tell me whether you wrote this code in separate js file or in App.js file?