51 lines
1.4 KiB
TypeScript
51 lines
1.4 KiB
TypeScript
import { useState, useEffect, useMemo } from 'react';
|
||
|
||
interface WindowSize {
|
||
width: number;
|
||
height: number;
|
||
isMobile: boolean;
|
||
}
|
||
|
||
/**
|
||
* 自定义Hook,用于获取并监听窗口大小变化
|
||
* @returns 当前窗口的宽度和高度以及是否为移动设备
|
||
*/
|
||
export function useWindowSize(): WindowSize {
|
||
// 初始化状态为 undefined,避免服务器端渲染问题
|
||
const [windowSize, setWindowSize] = useState<Omit<WindowSize, 'isMobile'>>({
|
||
width: typeof window !== 'undefined' ? window.innerWidth : 0,
|
||
height: typeof window !== 'undefined' ? window.innerHeight : 0,
|
||
});
|
||
|
||
// 判断是否为移动设备,默认小于768px为移动设备
|
||
const isMobile = useMemo(() => windowSize.width < 768, [windowSize.width]);
|
||
|
||
useEffect(() => {
|
||
// 只在客户端执行
|
||
if (typeof window === 'undefined') {
|
||
return;
|
||
}
|
||
|
||
// 处理窗口大小变化的函数
|
||
function handleResize() {
|
||
setWindowSize({
|
||
width: window.innerWidth,
|
||
height: window.innerHeight,
|
||
});
|
||
}
|
||
|
||
// 添加事件监听器
|
||
window.addEventListener('resize', handleResize);
|
||
|
||
// 确保初始状态正确
|
||
handleResize();
|
||
|
||
// 清理函数
|
||
return () => window.removeEventListener('resize', handleResize);
|
||
}, []); // 空依赖数组意味着这个effect只在组件挂载和卸载时运行
|
||
|
||
return { ...windowSize, isMobile };
|
||
}
|
||
|
||
export default useWindowSize;
|