Writing a Custom useWindowSize React Hook
Nick Scialli
April 18, 2020
New — Check out my free newsletter on how the web works!
One of the coolest parts about React Hooks is that you can create your own! In this post, we’ll quickly roll our own useWindowSize
hook.
What useWindowSize Will Do
Today we’re creating the useWindowSize
custom hook because we’d like to make sure we always have access to our window innerHeight
and innerWidth
properties when they change. To do this, we’ll tap into the window’s onresize
event listener.
Writing the Hook
Since we need to maintain the window size information, we’ll use useState
and default it to a two element array consisting of the initial window .
const { useState } = React;
function useWindowSize() {
const [size, setSize] = useState([window.innerHeight, window.innerWidth]);
return size;
}
Of course, this won’t be dynamic. To be dynamic, we’ll want to use the window resize event handler. Now, we only need to set the event listener once, so we’ll do this with a useEffect
hook with an empty dependency array.
const { useEffect, useState } = React;
function useWindowSize() {
const [size, setSize] = useState([window.innerHeight, window.innerWidth]);
useEffect(() => {
const handleResize = () => {
setSize([window.innerHeight, window.innerWidth]);
};
window.addEventListener('resize', handleResize);
}, []);
return size;
}
Awesome, so now we’ve added an event listener and we setSize
whenever our window is resized.
There’s one last thing we need to do: add a cleanup function to our useEffect
hook to make sure we remove the event listener when our component unmounts.
const { useEffect, useState } = React;
function useWindowSize() {
const [size, setSize] = useState([window.innerHeight, window.innerWidth]);
useEffect(() => {
const handleResize = () => {
setSize([window.innerHeight, window.innerWidth]);
};
window.addEventListener('resize', handleResize);
// Clean up!
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return size;
}
See It in Action
Our final code:
const { useEffect, useState } = React;
function useWindowSize() {
const [size, setSize] = useState([window.innerHeight, window.innerWidth]);
useEffect(() => {
const handleResize = () => {
setSize([window.innerHeight, window.innerWidth]);
};
window.addEventListener('resize', handleResize);
// Clean up!
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return size;
}
const App = () => {
const [height, width] = useWindowSize();
return (
<div className="box">
<h1>useWindowSize Hook</h1>
<p>
height: {height}
<br />
width: {width}
</p>
</div>
);
};
In codepen:
🎓 Learn how the web works
One of the best ways to level up your tech career is to have a great foundational understanding of how the web works. In my free newsletter, How the Web Works, I provide simple, bite-sized explanations for various web topics that can help you boost your knowledge. Join 2,500+ other learners on the newsletter today!
Signing up is free, I never spam, and you can unsubscribe any time. You won't regret it!
Sign up for the newsletter »Nick Scialli is a senior UI engineer at Microsoft.