Detecting Mobile Screen Size in React Using useEffect and window.matchMedia

When building responsive web applications, it’s essential to adapt the UI dynamically based on the screen size. A common requirement is to detect if a user is on a mobile device or not. In this blog, we'll explore a clean and effective way to achieve this in React using the useState and useEffect hooks, along with window.matchMedia.

const [isMobile, setIsMobile] = useState(false);

useEffect(() => {
  // Add a listener for changes to the screen size
  const mediaQuery = window.matchMedia("(max-width: 500px)");

  // Set the initial value of the `isMobile` state variable
  setIsMobile(mediaQuery.matches);

  // Define a callback function to handle changes to the media query
  const handleMediaQueryChange = (event) => {
    setIsMobile(event.matches);
  };

  // Add the callback function as a listener for changes to the media query
  mediaQuery.addEventListener("change", handleMediaQueryChange);

  // Remove the listener when the component is unmounted
  return () => {
    mediaQuery.removeEventListener("change", handleMediaQueryChange);
  };
}, []);

Explanation

State Initialization:

isMobile is a state variable that keeps track of whether the screen width is 500px or less.

Initially set to false.

Using window.matchMedia:

window.matchMedia is a browser API that matches a CSS media query string (e.g., (max-width: 500px)).

It returns a MediaQueryList object that tracks the state of the media query.

Setting Initial State:

setIsMobile(mediaQuery.matches) sets the initial state based on whether the screen width matches the media query.

Handling Media Query Changes:

A callback function handleMediaQueryChange updates the state (isMobile) whenever the screen size changes and matches the media query.

Adding and Removing Listeners:

The addEventListener("change", handleMediaQueryChange) method listens for screen size changes.

When the component unmounts, the listener is removed using removeEventListener to avoid memory leaks.

Why This Approach Works

This pattern ensures:

Real-time Updates: The app dynamically detects screen size changes and updates the UI accordingly.

Clean-Up: Removing the event listener on unmount prevents unnecessary operations and improves performance.

return (
  <div>
    {isMobile ? (
      <p>You're on a mobile device!</p>
    ) : (
      <p>You're on a desktop or larger screen!</p>
    )}
  </div>
);

Conclusion

By leveraging useState, useEffect, and window.matchMedia, you can efficiently detect screen size changes and manage responsive behaviors in React. This pattern is lightweight and easily integrates into modern React applications.