Hey Everyone!, Today we are going to discuss how to get a window's width and height with a custom hook. This coding exercise was asked of me in one of my interviews.
The interviewer asked me, Payal, create one custom hook (for reusing the code) to get the window's width and height dynamically when we resize it.
And I took time to determine that, but today I will make others understand in a 101 way.
So, let's not waste time and start...
I am going to divide it into a few steps. Let's follow these steps:
1. How to get the width and height of a browser window
In JavaScript, we use window.innerWidth and window.innerHeight to get the browser window width and height.
So, we can use the same concept in React too. Because ultimately, React is also a JavaScript library.
2. Let's use "window.innerWidth" and "window.innerHeight" properties.
App.js
import { useRef } from "react";
import "./App.css";
function App() {
const windowSize = useRef([
window.innerWidth,
window.innerHeight,
]);
return (
<div className="App">
<div className="window">
Width : <span>{windowSize.current[0]}</span>
</div>
<div className="window">
Height : <span>{windowSize.current[1]}</span>
</div>
</div>
);
}
export default App;
Here I used the useRef hook. We know useRef is a mutable object, and it doesn't change its value when a component is updated. Also, changing the value of current
property doesn't make it re-render.
So, if we need the window objects to change when we resize the browser object, useRef won't be the right choice.
So, we have to think: if we resize the window using an event listener, that means the state is changing while resizing, What if we use useState to track the state and provide us the value of windows dynamically?
Let's do it in our next step.
3.Add a resize event listener and useState for tracking the state in a custom hook:
useSize.js
import { useEffect, useState } from "react";
const useSize = () => {
const [windowSize, setWindowSize] = useState([
window.innerHeight,
window.innerWidth,
]);
useEffect(() => {
const windowSizeHandler = () => {
setWindowSize([window.innerWidth, window.innerHeight]);
};
window.addEventListener("resize", windowSizeHandler);
return () => {
window.removeEventListener("resize", windowSizeHandler);
};
}, []);
return windowSize;
};
export default useSize;
Let's break down the code step by step.
-
Let's make a
useSize
custom hook. In this custom hook, we used the built-in react hook useState, which updates the state variable whenever the window's width and height change.
const [windowSize, setWindowSize] = useState([
window.innerHeight,
window.innerWidth,
]);
A return value from useState is an array with the values "windowSize" and "setWindowSize." The state is stored in a variable named "windowSize," and anytime the function "setWindowSize" is invoked, it updates the state.
- useEffect used for the first re-render and when the dependency changes. But there is no dependency array for our case. So it gets called only once. For our case, we are adding a resize hook to the addEventListener() method as an action. As I mentioned, there is no dependency array in useEffect, so the callback function executed only once. That means an event listener is added to the window resize event during the initial rendering of the component, and it remains active throughout the component's lifecycle.
useEffect(() => {
const windowSizeHandler = () => {
setWindowSize([window.innerWidth, window.innerHeight]);
};
window.addEventListener("resize", windowSizeHandler);
- removeEventListener() is used to remove the resize event listener in this cleanup function to prevent memory leaks and unnecessary event handling after the component is removed from the DOM.
return () => {
window.removeEventListener("resize", windowSizeHandler);
};
- returning the
windowSize
variable to get thewindowSize
when we are going to use thisuseSize
custom hook in our different components.
return windowSize;
4.Update the App.js file.
We are importing the useSize
custom hook in App.js and utilising it like other hooks.
useSize() is passed to a variable and uses that variable to fetch the width and height from an array. because the windowSize
variable is initialised as an array in state.
App.js
import useSize from "./useSize";
import "./App.css";
function App() {
const windowsize = useSize();
return (
<div className="App">
<div className="window">
Width : <span>{windowsize[0]}</span>
</div>
<div className="window">
Height : <span>{windowsize[1]}</span>
</div>
</div>
);
}
export default App;
5. Hola, we get the output as we expected.😊
The window's width and height are updated when it's resized.
Conclusion
By using this hook in a functional component, you can access the current window size as an array and update it automatically whenever the window is resized.
That's All.
It's as easy as eating an ice cream.😋
I hope that was enjoyable.🥳
Happy Coding....👩💻
Top comments (9)
This post was a great starting point for me, I just made a few tweaks to get this running in the newer NextJS flavor of React where the DOM isn't available until inside useEffect():
WindowSize type:
hook:
I chose "outerHeight" because that's the number Bootstrap uses for its breakpoints. Works like a champ!!
Am glad that you liked it ☺️
What a well written post!
Thanks for the sharing, @payalsasmal , it helped my coding
I am glad that It helped you.
Nice Blog!
Thank you 🙏
do you have an idea why the initial size when you open up the page is way smaller for me?
i found the mistake, you switched the order of height and width in your useState and the eventhandler :
thats why it used the height as initial width and then when i changed the screen size it used the width again. they need to appear in the same order in both instances
other than that it works great, thank you!