如何编写自定义useWindowSize的React钩子

221 阅读1分钟

关于React钩子最酷的部分之一是你可以创建你自己的钩子在这篇文章中,我们将快速推出我们自己的useWindowSize 钩子。

useWindowSize将做什么

今天我们要创建useWindowSize 自定义钩子,因为我们想确保当我们的窗口innerHeightinnerWidth 属性发生变化时,我们总是能访问它们。要做到这一点,我们将利用窗口的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中。