Reputation: 414
I want to observer when window stop resizing, cause currently if i listen to the resize
event on window
, i could only listen to resizing change
but not knowing when resizing stops. I checked the event
parameter in resizing callback, but did not find and helpful information.
Below is the code i'm trying to complete:
import React, { useState, useEffect } from "react";
export default function App() {
const [windowResizing, setWindowResizing] = useState(false);
const handleWindowResize = e => {
setWindowResizing(true);
};
useEffect(() => {
window.addEventListener("resize", handleWindowResize);
return () => window.removeEventListener("resize", handleWindowResize);
}, []);
return <div>{JSON.stringify({ windowResizing })}</div>;
}
But this does not work, since windowResizing
will keep being true
after resizing begins, even i already stops resizing.
So is there any way to observe when window stop resizing and i can then call setState
based on that?
Upvotes: 1
Views: 5355
Reputation: 35
Small update to Tholle's answer
to include the size and the resizing state
import { useState, useLayoutEffect } from 'react'
// https://stackoverflow.com/a/63010184
function debounce(fn, ms) {
let timer;
return _ => {
clearTimeout(timer);
timer = setTimeout(_ => {
timer = null;
fn.apply(this, arguments);
}, ms);
};
}
const useWindowSize = () => {
const [size, setSize] = useState([0, 0, false]);
useLayoutEffect(() => {
let timeout;
clearTimeout(timeout);
function updateSize() {
clearTimeout(timeout);
setSize([window.innerWidth, window.innerHeight, true]);
timeout = setTimeout(() => {
setSize([window.innerWidth, window.innerHeight, false]);
}, 800);
}
const debouncedResizeHandler = debounce(() => updateSize())
window.addEventListener('resize', debouncedResizeHandler);
setSize([window.innerWidth, window.innerHeight, false]);
return () => window.removeEventListener('resize', debouncedResizeHandler);
}, []);
return size;
}
export default useWindowSize
Upvotes: 0
Reputation: 112917
There is no real "resizing state" in the browser; the resize
event occurs and then it's over.
You could emulate a resizing state of your own by setting a state variable to true
on every resize
event, and start a new timeout that will reset it back to false
after a small amount of time.
Example
import React, { useState, useEffect } from "react";
export default function App() {
const [windowResizing, setWindowResizing] = useState(false);
useEffect(() => {
let timeout;
const handleResize = () => {
clearTimeout(timeout);
setWindowResizing(true);
timeout = setTimeout(() => {
setWindowResizing(false);
}, 200);
}
window.addEventListener("resize", handleResize);
return () => window.removeEventListener("resize", handleResize);
}, []);
return <div>{JSON.stringify({ windowResizing })}</div>;
}
Upvotes: 3