DEV Community

Cover image for useBreakpoint - React Hook
Pavan Chilukuri
Pavan Chilukuri

Posted on

useBreakpoint - React Hook

I have come across a use case where I had to display content based on the device width. I was using Material-UI's Grid component which added responsiveness to my web application. However, there are few things I did not want to be seen on the mobile screens. For instance, a long expanded list of Menu items might not be necessary to occupy your whole screen on the mobile device.

To solve the above problem, I wrote a custom hook to get the screen width. The useBreakpoint hook will return one of the breakpoints based on the device width. The below table would help determine the breakpoints for various device widths.

Width 0px 600px 960px 1280px 1920px
Breakpoint xs sm md lg xl
Devices Extra Small Small Medium Large Extra Large

I made use of JavaScript EventTarget's addEventListener() function on window object to handle the resizing of the device width.

From Mozilla Docs,

The EventTarget method addEventListener() sets up a function that will be called whenever the specified event is delivered to the target. Common targets are Element, Document, and Window, but the target may be any object that supports events (such as XMLHttpRequest).

addEventListener() works by adding a function or an object that implements EventListener to the list of event listeners for the specified event type on the EventTarget on which it's called.

Ok, enough said. Let's have a glimpse at the code 👀

1️⃣ Set initial values for breakpoint and windowSize objects.

  const [breakpoint, setBreakPoint] = useState('');
  const [windowSize, setWindowSize] = useState({
    width: undefined,
    height: undefined,
  });
Enter fullscreen mode Exit fullscreen mode

2️⃣ A range of device widths following the above table to define or setting the breakpoint.

    if (0 < windowSize.width && windowSize.width < 600) {
      setBreakPoint(breakpoints[0]);
    }
    if (600 < windowSize.width && windowSize.width < 960) {
      setBreakPoint(breakpoints[600]);
    }
    if (960 < windowSize.width && windowSize.width < 1280) {
      setBreakPoint(breakpoints[960]);
    }
    if (1280 < windowSize.width && windowSize.width < 1920) {
      setBreakPoint(breakpoints[1280]);
    }
    if (windowSize.width >= 1920) {
      setBreakPoint(breakpoints[1920]);
    }
Enter fullscreen mode Exit fullscreen mode

3️⃣ A function that can continuously handle updating width and height of the windowSize.

  const handleResize = () => {
    setWindowSize({
      width: window.innerWidth,
      height: window.innerHeight,
    });
  };
Enter fullscreen mode Exit fullscreen mode

4️⃣ Finally, a useEffect hook to hold everything together. It accepts windowSize.width as a dependency since we have to handle resizing of window based on the width of the device or browser.

  useEffect(() => {
    window.addEventListener('resize', handleResize);
    handleResize();

    if (0 < windowSize.width && windowSize.width < 600) {
      setBreakPoint(breakpoints[0]);
    }
    if (600 < windowSize.width && windowSize.width < 960) {
      setBreakPoint(breakpoints[600]);
    }
    if (960 < windowSize.width && windowSize.width < 1280) {
      setBreakPoint(breakpoints[960]);
    }
    if (1280 < windowSize.width && windowSize.width < 1920) {
      setBreakPoint(breakpoints[1280]);
    }
    if (windowSize.width >= 1920) {
      setBreakPoint(breakpoints[1920]);
    }

    return () => window.removeEventListener('resize', handleResize);
  }, [windowSize.width]);
Enter fullscreen mode Exit fullscreen mode

That concludes everything. Feel free to checkout the source code. Let me know if you have any suggestions or questions.

Top comments (1)

Collapse
 
sirclesam profile image
Sirclesam

MUI now has a builtin useMediaQuery hook that does essentially this:

mui.com/material-ui/react-use-medi...