useBreakpoint - React Hook
Tags: react, webdev, discuss
Published: 2021-06-15 22:11:17


I have come across a use case where I had to display content based on the device width. I was using [Material-UI](https://material-ui.com/)'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.

{% codesandbox i13rx %}

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](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener),

> 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 :eyes:

:one: Set initial values for `breakpoint` and `windowSize` objects.
```jsx
  const [breakpoint, setBreakPoint] = useState('');
  const [windowSize, setWindowSize] = useState({
    width: undefined,
    height: undefined,
  });
```
:two: A range of device widths following the above table to define or setting the breakpoint.

```jsx
    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]);
    }
```
:three: A function that can continuously handle updating width and height of the `windowSize`.

```jsx
  const handleResize = () => {
    setWindowSize({
      width: window.innerWidth,
      height: window.innerHeight,
    });
  };
```
:four: 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.
```jsx
  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]);
```
That concludes everything. Feel free to checkout the [source code](https://github.com/chilupa/useBreakpoint-hook). Let me know if you have any suggestions or questions.