Responsive React Application with the useMediaQuery Hook

December 30, 2023 (1y ago)

0 views

In the world of web development, creating responsive and adaptive user interfaces is a crucial aspect of delivering a seamless experience across various devices. Responsive design ensures that your web application looks and functions well on everything from large desktop monitors to small mobile screens.

In this article, we'll explore the creation of a custom React hook, useMediaQuery, that leverages the power of React's hooks and the window.matchMedia API to facilitate responsive design in React applications.

Understanding the Need for Responsiveness

Before diving into the implementation, let's briefly discuss why responsiveness is important.

With the proliferation of different devices and screen sizes, it's essential to design applications that adapt to varying viewport dimensions.

This adaptability not only enhances the user experience but also caters to an ever-expanding array of devices.

The useMediaQuery Hook

Introduction

The useMediaQuery hook is a simple yet powerful tool that allows developers to conditionally render components or apply styles based on the current window size. It takes advantage of the window.matchMedia API, providing a clean and efficient way to manage media queries in a React application.

Implementation

Let's take a closer look at the implementation of the useMediaQuery hook:

import { useEffect, useState, useMemo } from "react";
 
type Breakpoint = "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
type MediaQuery = Record<Breakpoint, string>;
 
const mediaQueries: MediaQuery = {
  xs: "(min-width: 480px)",
  sm: "(min-width: 640px)",
  md: "(min-width: 768px)",
  lg: "(min-width: 1024px)",
  xl: "(min-width: 1280px)",
  "2xl": "(min-width: 1536px)",
};
 
const useMediaQuery = (breakpoint: Breakpoint = "md"): boolean => {
  const mediaQuery = mediaQueries[breakpoint];
  const mediaQueryList = useMemo(() => window.matchMedia(mediaQuery), [mediaQuery]);
  const [matches, setMatches] = useState(mediaQueryList.matches);
 
  useEffect(() => {
    const handleChange = (event: MediaQueryListEvent) => {
      setMatches(event.matches);
    };
 
    mediaQueryList.addEventListener("change", handleChange);
 
    return () => {
      mediaQueryList.removeEventListener("change", handleChange);
    };
  }, [mediaQueryList]);
 
  if (!mediaQueries[breakpoint]) {
    console.error(`Invalid breakpoint: ${breakpoint}`);
    return false;
  }
 
  return matches;
};
 
export default useMediaQuery;

How to Use

To use the useMediaQuery hook in your React components, import it and incorporate it as follows:

import React from "react";
import useMediaQuery from "./useMediaQuery";
 
const MyComponent = () => {
  const isSmallScreen = useMediaQuery("sm");
 
  return (
    <div>
      {isSmallScreen ? <p>Small Screen Content</p> : <p>Large Screen Content</p>}
    </div>
  );
};
 
export default MyComponent;

Key Features and Benefits

1. Simplifying Responsive Design

The useMediaQuery hook abstracts away the complexity of handling media queries directly in components, providing a clean and reusable solution.

This separation of concerns enhances code readability and maintainability.

2. Customizable Breakpoints

Tailwind CSS-inspired breakpoints make it easy to define and use breakpoints that align with your design preferences.

The useMediaQuery hook allows you to specify the desired breakpoint, enabling fine-grained control over your responsive layout.

3. Memoization for Performance

The hook incorporates the useMemo hook to optimize performance by memoizing the mediaQueryList. This ensures that unnecessary re-renders are avoided when the breakpoint prop remains unchanged.

4. Error Handling

The hook includes error handling to log a console error if an invalid breakpoint is provided. This helps catch potential issues during development.

Conclusion

In this article, we've explored the creation and usage of the useMediaQuery hook for building responsive React applications. By providing a simple interface to manage media queries, this custom hook empowers developers to create interfaces that seamlessly adapt to various screen sizes.

Integrating the useMediaQuery hook into your projects can significantly enhance the responsiveness of your applications, contributing to a positive user experience across diverse devices.

Feel free to customize and extend the hook based on your specific project requirements, and don't forget to share your thoughts and experiences with this hook in the comments (if exists) below!

Happy coding!