调整浏览器大小时如何调用useEffect
How to call useEffect when browser is resized
我需要 bootstrap 个在 react-slick 旋转木马中等高的卡片。我从以下 post 中找到了解决方案:
下面是我的代码,它记录了包含 bootstrap 卡片的旋转木马 div 的高度。然后将捕获的高度作为道具传递给 bootstrap 卡片。
const [upcomingEventsHeight, setUpcomingEventsHeight] = React.useState("auto");
React.useEffect(() => {
setTimeout(
() => {
const height = document.getElementsByClassName("slick-track")[0].clientHeight;
setUpcomingEventsHeight(height + "px");
}, 3000);
}, []);
它工作正常,除非调整浏览器大小时,因为高度仅在首次呈现页面时设置。
我认为我需要在调整浏览器大小时重新呈现页面,我知道我可以使用
window.addEventListener('resize', ...);
但是,我收到以下代码的错误,因为无法在回调中调用 React.useEffect。
window.addEventListener('resize', () => {
React.useEffect(() => {
setTimeout(
() => {
const height = document.getElementsByClassName("slick-track")[0].clientHeight;
setUpcomingEventsHeight(height + "px");
}, 3000);
}, []);
});
我不确定如何解决这个问题,因为我想使用 useEffect 重新呈现页面。
您想使用 useEffect
添加事件侦听器(并删除它)。
const handleResize = () => {
...
}
React.useEffect(() => {
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, [])
这将在呈现组件时添加事件侦听器,并在未呈现时将其删除(useEffect
的 return 值在清理时为 运行)。每当第二个参数中的数组中的变量发生变化时,useEffect
将 运行(在这种情况下,它保留为空 [],因此它只会 运行 一次)。
此外,您应该考虑使用“去抖动”功能,而不是使用 setTimeout,this post explains how they work。您可以在 npm 和 lodash 等中找到可重用的去抖功能。
这对于很多项目来说是棘手但微不足道的。
你的useEffect会被触发一次,每次用户调整浏览器大小时都会触发里面的函数。
有时,当您调整浏览器大小时,您无法访问状态或设置状态(使用 useState),所以我喜欢将 window 的 width
的值放在外面。这样我就可以在几乎没有冲突的情况下随时重用这些值。
// react using hooks
import { useState, useEffect } from 'react';
// use outside the component
let isMobile = true; // variable to check width
const MyComponent = () => {
// optional: save the width of the window using state
const [width, setWidth] = useState(window.innerWidth); // check width size of the window
const handleWindowSizeChange = () => {
setWidth(window.innerWidth);
isMobile = window.innerWidth < 700 ? true : false;
};
// call your useEffect
useEffect(() => {
window.addEventListener('resize', handleWindowSizeChange);
return () => {
window.removeEventListener('resize', handleWindowSizeChange);
};
}, []);
// view of the component
return (<h1>{isMobile}</h1>)
}
你实际上应该使用 useLayoutEffect
来处理这种计算,因为它是在组件渲染时触发的(在计算完成后,但在绘制完成之前),而不是 useEffect,即在组件呈现后运行。
我需要 bootstrap 个在 react-slick 旋转木马中等高的卡片。我从以下 post 中找到了解决方案:
下面是我的代码,它记录了包含 bootstrap 卡片的旋转木马 div 的高度。然后将捕获的高度作为道具传递给 bootstrap 卡片。
const [upcomingEventsHeight, setUpcomingEventsHeight] = React.useState("auto");
React.useEffect(() => {
setTimeout(
() => {
const height = document.getElementsByClassName("slick-track")[0].clientHeight;
setUpcomingEventsHeight(height + "px");
}, 3000);
}, []);
它工作正常,除非调整浏览器大小时,因为高度仅在首次呈现页面时设置。
我认为我需要在调整浏览器大小时重新呈现页面,我知道我可以使用
window.addEventListener('resize', ...);
但是,我收到以下代码的错误,因为无法在回调中调用 React.useEffect。
window.addEventListener('resize', () => {
React.useEffect(() => {
setTimeout(
() => {
const height = document.getElementsByClassName("slick-track")[0].clientHeight;
setUpcomingEventsHeight(height + "px");
}, 3000);
}, []);
});
我不确定如何解决这个问题,因为我想使用 useEffect 重新呈现页面。
您想使用 useEffect
添加事件侦听器(并删除它)。
const handleResize = () => {
...
}
React.useEffect(() => {
window.addEventListener('resize', handleResize)
return () => window.removeEventListener('resize', handleResize)
}, [])
这将在呈现组件时添加事件侦听器,并在未呈现时将其删除(useEffect
的 return 值在清理时为 运行)。每当第二个参数中的数组中的变量发生变化时,useEffect
将 运行(在这种情况下,它保留为空 [],因此它只会 运行 一次)。
此外,您应该考虑使用“去抖动”功能,而不是使用 setTimeout,this post explains how they work。您可以在 npm 和 lodash 等中找到可重用的去抖功能。
这对于很多项目来说是棘手但微不足道的。 你的useEffect会被触发一次,每次用户调整浏览器大小时都会触发里面的函数。
有时,当您调整浏览器大小时,您无法访问状态或设置状态(使用 useState),所以我喜欢将 window 的 width
的值放在外面。这样我就可以在几乎没有冲突的情况下随时重用这些值。
// react using hooks
import { useState, useEffect } from 'react';
// use outside the component
let isMobile = true; // variable to check width
const MyComponent = () => {
// optional: save the width of the window using state
const [width, setWidth] = useState(window.innerWidth); // check width size of the window
const handleWindowSizeChange = () => {
setWidth(window.innerWidth);
isMobile = window.innerWidth < 700 ? true : false;
};
// call your useEffect
useEffect(() => {
window.addEventListener('resize', handleWindowSizeChange);
return () => {
window.removeEventListener('resize', handleWindowSizeChange);
};
}, []);
// view of the component
return (<h1>{isMobile}</h1>)
}
你实际上应该使用 useLayoutEffect
来处理这种计算,因为它是在组件渲染时触发的(在计算完成后,但在绘制完成之前),而不是 useEffect,即在组件呈现后运行。