How to Create your Own useWindowSize Hook in ReactJS
Tags: react, beginners, tutorial, webdev
Published: 2023-04-01 07:43:00

{% youtube nplOYEfrbXU %}

## Introduction:
As a ReactJS developer, you may encounter situations where you need to dynamically show or hide a component or element based on the browser's window dimensions. Normally, CSS Media Queries are used for this purpose, but if you are using ReactJS, you can also use the **useWindowSize** hook to dynamically render a component or element. Therefore, in this tutorial, I will guide you through the process of creating your custom **useWindowSize** hook.

## Approach:
We will conditionally render the div named **medium** when the screen width is greater than **750px**, and we will also render the div named **large** when the screen width is greater than **1024px**.

### App.js
```react
// global stylesheet
import "./styles.css";

export default function App() {
  return (
    <div className="container">
      <div className="box">Small</div>
      <div className="box">Medium</div>
      <div className="box">Large</div>
    </div>
  );
}
```
In the above **App.js** component, we have a parent div with the class **container** and three child elements with the class **box**.

### styles.css
```css
.container {
  display: flex;
  justify-content: center;
  gap: 2rem;
}

.box {
  background-color: coral;
  padding: 2rem;
  color: white;
  font-weight: bold;
  border-radius: 1rem;
}
```
We added some styles to the **"container"** class and **"box"** class in the global stylesheet to improve their appearance.

### useWindowSize Hook
It's time to create our **useWindowSize** hook. To do so, navigate to the **src** folder, and if you haven't already, create a **hooks** folder within it. Next, create a file named **useWindowSize.js**.

## useWindowSize.js
```react
import { useState, useEffect } from "react";

function useWindowSize() {
  // Initial screen width and height
  const [screenWidth, setScreenWidth] = useState(window.innerWidth);
  const [screenHeight, setScreenHeight] = useState(window.innerHeight);

  // Will run after mount
  useEffect(() => {
    // function to update screenWidth & screenHeight states
    function handleResize() {
      setScreenWidth(window.innerWidth);
      setScreenHeight(window.innerHeight);
    }

    // listen to resize event and update states
    window.addEventListener("resize", handleResize);

    // cleanup function to safely remove eventListener
    return () => window.removeEventListener("resize", handleResize);
  }, []);

  return { screenWidth, screenHeight };
}

export default useWindowSize;
```
We've initialized the **screenWidth** and **screenHeight** states with the height and width of the browser viewport. Within the **useEffect** hook, we've defined a function named **handleResize**, which updates the **screenWidth** and **screenHeight** states whenever the user resizes the browser window. To enable this functionality, we've added an event listener that listens to the resize event and calls the **handleResize** function to update the states accordingly. Finally, we've implemented a cleanup function that safely removes the event listener.

## Using useWindowSize Hook
Now that our **useWindowSize** hook is ready to use, let's import it into the **App.js** component and use it to conditionally render the **medium** and **large** named divs.

### App.js
```react
// global stylesheet
import "./styles.css";

// hook
import useWindowSize from "./hooks/useWindowSize";

export default function App() {
  // Using screenWidth state from useWindowSize hook
  const { screenWidth } = useWindowSize();

  return (
    <div className="container">
      <div className="box">Small</div>

      {/* Conditionally showing Medium named div */}
      {screenWidth > 750 ? <div className="box">Medium</div> : null}

      {/* Conditionally showing Large named div */}
      {screenWidth > 1024 ? <div className="box">Large</div> : null}
    </div>
  );
}
```

I hope this has been helpful and informative for you. If you have any questions, comments, or feedback, feel free to leave a comment below! Happy coding! ❤