DEV Community

Soumya Ranjan Padhy
Soumya Ranjan Padhy

Posted on

useScreenSize: A Custom React Hook for Dynamic Screen Size Detection

Everyone knows responsive design is crucial for a seamless user experience across devices. While CSS frameworks offer utility classes for screen sizes, detecting screen size programmatically can be useful sometimes. This is where the useScreenSize React hook comes in.

What is useScreenSize?

The "useScreenSize" hook allows you to dynamically detect the current screen size and respond to changes in real-time. This hook returns screen size values like "xs", "sm", "md", "lg", "xl", and "2xl", which correspond to the screen widths used in popular CSS frameworks such as Tailwind CSS.

Let's make it

1.Define the hook

export const useScreenSize = () => {}
Enter fullscreen mode Exit fullscreen mode

2.Managing State with useState

import {useState} from "react";

export const useScreenSize = () => {
  const [screenSize, setScreenSize] = useState<
    "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | ""
  >("");
}
Enter fullscreen mode Exit fullscreen mode

We use the useState hook to create a state variable screenSize that can take one of several string values representing different screen size categories: "xs", "sm", "md", "lg", "xl", and "2xl". The default value is an empty string (""), which will be updated once the screen size is determined.
3.Detecting Window Resize Events

import {useState, useEffect} from "react";

export const useScreenSize = () => {
  const [screenSize, setScreenSize] = useState<
    "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | ""
  >("");

  useEffect(() => {
    const handleResize = () => {
      if (window.innerWidth < 640) {
        setScreenSize("xs");
      } else if (window.innerWidth >= 640 && window.innerWidth < 768) {
        setScreenSize("sm");
      } else if (window.innerWidth >= 768 && window.innerWidth < 1024) {
        setScreenSize("md");
      } else if (window.innerWidth >= 1024 && window.innerWidth < 1280) {
        setScreenSize("lg");
      } else if (window.innerWidth >= 1280 && window.innerWidth < 1536) {
        setScreenSize("xl");
      } else if (window.innerWidth >= 1536) {
        setScreenSize("2xl");
      }
    };

    window.addEventListener("resize", handleResize);
    handleResize();

    return () => window.removeEventListener("resize", handleResize);
  }, []);

}
Enter fullscreen mode Exit fullscreen mode

useEffect: This ensures that the screen size is calculated after the component mounts, and it updates dynamically as the user resizes the window.

handleResize: Inside this function, we check the width of the browser window using window.innerWidth and set the screenSize accordingly:
Below 640 pixels: "xs"
640–768 pixels: "sm"
768–1024 pixels: "md"
1024–1280 pixels: "lg"
1280–1536 pixels: "xl"
Above 1536 pixels: "2xl"

Event Listener: We attach the resize event listener to trigger the "handleResize" function every time the window is resized. This ensures that "screenSize" stays up-to-date.

Cleanup: The return function within "useEffect" removes the resize event listener when the component unmounts, preventing potential memory leaks.

How to Use useScreenSize in Your Component

import React from "react";
import useScreenSize from "./useScreenSize";

const MyResponsiveComponent = () => {
  const screenSize = useScreenSize();

  return (
    <div>
      <h1>Current screen size: {screenSize}</h1>
      {screenSize === "xs" && <p>This is a mobile-sized screen!</p>}
      {screenSize === "lg" && <p>You are viewing this on a large screen.</p>}
    </div>
  );
};

export default MyResponsiveComponent;
Enter fullscreen mode Exit fullscreen mode

In this example, the screen size is dynamically detected and displayed in the component. We also use the detected "screenSize" to conditionally render different content based on the user's device.

Conclusion

Reactivity: The hook automatically detects screen size changes and updates the UI in real-time.

Flexibility: By handling screen sizes programmatically, you can conditionally render different components or styles in your React app.

Customization: You can easily modify the breakpoints in the hook to match your specific design requirements.

Feel free to try out this hook in your projects! Let me know your thoughts, and happy coding!

Top comments (4)

Collapse
 
phenax profile image
Akshay Nair

Alternatively you can use matchMedia to use css media queries for breakpoints.

const match = window.matchMedia('(min-width: 800px)')
match.addEventListener('change', (e) => {
  const isMd = e.matches;
  // ...
});
Enter fullscreen mode Exit fullscreen mode
Collapse
 
soumyarian profile image
Soumya Ranjan Padhy • Edited

Thank you for sharing, this looks pretty clean.

Collapse
 
khangnd profile image
Khang

matchMedia is more performant :)

Collapse
 
goobergreve09 profile image
Greg G.

Thank you!