DEV Community

Cover image for How to Create your Own useWindowSize Hook in ReactJS
Kunal Ukey
Kunal Ukey

Posted on

How to Create your Own useWindowSize Hook in ReactJS

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

// 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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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

.container {
  display: flex;
  justify-content: center;
  gap: 2rem;
}

.box {
  background-color: coral;
  padding: 2rem;
  color: white;
  font-weight: bold;
  border-radius: 1rem;
}
Enter fullscreen mode Exit fullscreen mode

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

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;
Enter fullscreen mode Exit fullscreen mode

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

// 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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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! ❤

Top comments (0)