>我创建简单的自定义钩子来保存屏幕高度和宽度。 问题是我只想在我的状态中发生某些情况时才重新渲染(更新状态),而不是在每个调整大小事件中。 我首先尝试简单的实现:
const useScreenDimensions = () => {
const [height, setHeight] = useState(window.innerWidth);
const [width, setWidth] = useState(window.innerHeight);
const [sizeGroup, setSizeGroup]useState(getSizeGroup(window.innerWidth));
useEffect(() => {
const updateDimensions = () => {
if (getSizeGroup() !== sizeGroup) {
setSizeGroup(getSizeGroup(width));
setHeight(window.innerHeight);
setWidth(window.innerWidth);
}
};
window.addEventListener('resize', updateDimensions);
return () => window.removeEventListener('resize', updateDimensions);
}, [sizeGroup, width]);
return { height, width };
}
这种方法的问题在于每次都会调用效果,我希望效果在没有依赖项(sizeGroup,宽度)的情况下只调用一次,因为我不想每次屏幕宽度/大小组(window.addEventListener)发生变化时都注册事件。
因此,我尝试使用UseCallBack使用这种方法,但是每次状态发生任何更改时,我的"useEffect"函数都会调用多次。
//useState same as before..
const updateDimensions = useCallback(() => {
if (getSizeGroup(window.innerWidth) !== sizeGroup) {
setSizeGroup(getSizeGroup(width));
setHeight(window.innerHeight);
setWidth(window.innerWidth);
}
}, [sizeGroup, width]);
useEffect(() => {
window.addEventListener('resize', updateDimensions);
return () => window.removeEventListener('resize', updateDimensions);
}, [updateDimensions]);
....
return { height, width };
问题是对于我的目的来说,正确有效的方法是什么?我只想"注册"事件一次,并且仅在我的状态变量为 true 时才更新我的状态,而不是每次更新宽度或其他内容时。
我知道当您将空数组设置为"UseEffect"的第二个参数时,它只运行一次,但就我而言,我希望我的事件侦听器的寄存器运行一次,并且在调整大小时,我只会在某些条件为 true 时更新状态
多谢。
使用 2 种不同的用途效果
第一个用于注册事件。因此,下面的代码将在组件DidMount时运行。
useEffect(() => {
window.addEventListener('resize', updateDimensions);
}, []);
第二个使用效果基于状态更改运行。
useEffect(() => {
updateDimensions();
return () => window.removeEventListener('resize', updateDimensions);
}, [sizeGroup, width])
const updateDimensions = useCallback(() => {
setSizeGroup(getSizeGroup(width));
setHeight(window.innerHeight);
setWidth(window.innerWidth);
}
我不确定是否需要使用回调函数。而且我还没有测试过这段代码。