Custom Hooks in React: useMediaQuery

Welcome to my blog 👋🏽
I'm a Front-End Developer with a passion for learning!
I write about Programming 👩🏽💻 and Productivity Tips ✅
Search for a command to run...

Welcome to my blog 👋🏽
I'm a Front-End Developer with a passion for learning!
I write about Programming 👩🏽💻 and Productivity Tips ✅
No comments yet. Be the first to comment.
In this series, you will find custom React hooks for solving common coding challenges.
Retrieving data from an API is an extremely common task for a developer. Because this is such a frequent operation to complete, it's beneficial to abstract the internals and boilerplate of this functionality into a reusable hook. In this tutorial, yo...
Although my experience is primarily with front-end development, my current job is affording me the opportunity to do more full-stack work. Naturally, this meant that I needed to explore the different database GUIs available on the market. Here is a l...

A Note on the Series: Fast Fridays 🏎 is a series where you will find fast, short, and sweet tips/hacks that you may or may not be aware of. I will try to provide these (fairly) regularly on Fridays. In this Fast Friday tip, I'll explain how to crea...

Over the past year, I’ve started incorporating a Git GUI into my workflow. I still reach for the terminal about 90% of the time, but I’ve found that a GUI can really shine when it comes to things like viewing diffs, checking stashes, or resolving mer...

Simplifying Branch Management with Git Worktree

With all the AI tools popping up these days, I figured I'd try out some speech-to-text software in an attempt to boost my productivity. I've been hearing a lot about “developing at the speed of thought”, so here's a list of the top speech-to-text sof...

The addition of hooks in React 16.8 added massive improvements and made it easier than ever to reuse functionality between components. There are pre-defined hooks like useState and useEffect but, there is also the ability to create custom hooks to suit your needs.
In this tutorial, you'll learn how to create a hook, useMediaQuery, that can help with conditionally rendering JSX based on specified media queries.
A custom Hook is a JavaScript function whose name starts with ”use” and that may call other Hooks.
React Docs
Custom hooks are just functions that can be used within other components. Custom hooks are unique because they can handle their own state and side effects. One of the biggest benefits of being able to build your own hooks is that it provides a convenient way to share reusable logic between components that weren't possible before.
Let's say you want to conditionally render a component on a page at a certain media query breakpoint. For example, I encountered this issue at work while implementing a new tablet layout for our application.
Unfortunately, this isn't the most natural thing to do in React since you'd have to do some CSS trickery to hide the element at the right breakpoint. Although this is possible, there is a better way!
window.matchMedia()The main utility behind this custom hook is the window.matchMedia() method that returns a MediaQueryList object. The window.matchMedia() method accepts a single parameter, mediaQueryString, that specifies the media query to observe.
The MediaQueryList object contains properties and events that provide the ability to detect media query "targets" and will keep track of changes as the screen resizes. One of those properties, matches, returns a boolean indicating if the document currently matches the specified media query.
To understand the internals of the hook, let's first take a look at the finished code and then break it down. This example uses TypeScript but can easily be applied to a non-TypeScript implementation.
import { useEffect, useState } from "react";
function useMediaQuery(mediaQuery: string): boolean {
const [isMediaMatch, setIsMediaMatch] = useState(window.matchMedia(mediaQuery).matches);
useEffect(() => {
const mediaQueryList = window.matchMedia(mediaQuery);
const mqlHandler = () => setIsMediaMatch(mediaQueryList.matches);
mediaQueryList.addEventListener("change", mqlHandler);
return () => {
mediaQueryList.removeEventListener("change", mqlHandler);
};
}, [mediaQuery]);
return isMediaMatch;
}
export default useMediaQuery;
useMediaQuery function that accepts a single parameter representing the media query string.matches property. We also create a useEffect that will handle all the side effects needed to make things work.mediQueryList variable that will hold the MediaQueryList object.mqlHandler, to the mediaQueryList object that will update the state whenever there is a change to the evaluated result of the matches property. In the useEffect cleanup method, we remove the event listener to prevent lingering subscriptions when the component unmounts.isMediaMatch state which contains the value from the mediaQueryList.matches property.Leveraging our custom hook is pretty straightforward. All we have to do is define a variable that holds the boolean returned from the hook and reference that to conditionally render certain JSX based on the size of the page.
import useMediaQuery from "./hooks/useMediaQuery";
export default function App() {
const showTabletView = useMediaQuery(
"(min-width: 768px) and (max-width: 1024px)"
);
return (
<div>
<h1>useMediaQuery</h1>
{showTabletView ? (<h2>📱Tablet view</h2>)
: (<h2>This is the default view</h2>)}
</div>
);
}
Sample component showing how to leverage the useMediaQuery hook
Gif showing the useMediaQuery hook in action based on the code block above
I was pleasantly surprised to see how simple it was to implement a hook like this. I hope this hook proves to be useful for you and, I look forward to creating more articles on other customized hooks I've created for my project needs.
If you enjoy what you read, feel free to like this article or subscribe to my newsletter, where I write about programming and productivity tips.
As always, thank you for reading, and happy coding!