关于React钩子最酷的部分之一是你可以创建你自己的钩子在这篇文章中,我们将快速推出我们自己的useWindowSize
钩子。
useWindowSize将做什么
今天我们要创建useWindowSize
自定义钩子,因为我们想确保当我们的窗口innerHeight
和innerWidth
属性发生变化时,我们总是能访问它们。要做到这一点,我们将利用窗口的onresize
事件监听器。
编写钩子
由于我们需要维护窗口的大小信息,我们将使用useState
,并将其默认为一个由初始窗口的两个元素数组。
const { useState } = React;
function useWindowSize() {
const [size, setSize] = useState([window.innerHeight, window.innerWidth]);
return size;
}
当然,这不会是动态的。为了实现动态,我们要使用窗口大小调整事件处理程序。现在,我们只需要设置一次事件监听器,所以我们将用一个useEffect
钩子和一个空的依赖数组来做这件事。
const { useEffect, useState } = React;
function useWindowSize() {
const [size, setSize] = useState([window.innerHeight, window.innerWidth]);
useEffect(() => {
const handleResize = () => {
setSize([window.innerHeight, window.innerWidth]);
};
window.addEventListener('resize', handleResize);
}, []);
return size;
}
太棒了,所以现在我们已经添加了一个事件监听器,每当我们的窗口被调整大小时,我们setSize
。
我们还需要做最后一件事:给我们的useEffect
钩子添加一个清理函数,以确保我们在组件卸载时删除事件监听器。
const { useEffect, useState } = React;
function useWindowSize() {
const [size, setSize] = useState([window.innerHeight, window.innerWidth]);
useEffect(() => {
const handleResize = () => {
setSize([window.innerHeight, window.innerWidth]);
};
window.addEventListener('resize', handleResize);
// Clean up!
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return size;
}
看它在行动中
我们的最终代码。
const { useEffect, useState } = React;
function useWindowSize() {
const [size, setSize] = useState([window.innerHeight, window.innerWidth]);
useEffect(() => {
const handleResize = () => {
setSize([window.innerHeight, window.innerWidth]);
};
window.addEventListener('resize', handleResize);
// Clean up!
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return size;
}
const App = () => {
const [height, width] = useWindowSize();
return (
<div className="box">
<h1>useWindowSize Hook</h1>
<p>
height: {height}
<br />
width: {width}
</p>
</div>
);
};
在codepen中。