React---自定义React Hooks

31 阅读1分钟

juejin.cn/post/719694…

useWindowSize

使用场景:某些场景下需要获取用户窗口的宽度和高度(响应式设计时)

import { useState, useEffect } from "react";

const useWindowSize = () => {
  const getWindowSize = () => ({
    innerHeight: window.innerHeight,
    innerWidth: window.innerWidth,
    outerHeight: window.outerHeight,
    outerWidth: window.outerWidth,
  })

  const [windowSize, setWindowSize] = useState(getWindowSize())

  const handleResize = () => {
    setWindowSize(getWindowSize())
  }

  useEffect(() => {
    window.addEventListener('resize', handleResize)

    return () => {
      window.removeEventListener('resize', handleResize)
    }
  }, [])

  return windowSize
}

用法示例:

import { useWindowSize } from './hooks'

function App() {
  const windowSize = useWindowSize()

  return (
    <div>
      <ul>
        <li>window inner width: {windowSize.innerWidth}</li>
        <li>window inner height: {windowSize.innerHeight}</li>
        <li>window outer width: {windowSize.outerWidth}</li>
        <li>window outer height: {windowSize.outerHeight}</li>
      </ul>
    </div>
  )
}

useInterval

和 setInterval 函数一样,这个 hooks 有很多用途,比如动画、定期更新数据,甚至设置计时器:

import { useState, useEffect, useRef } from "react";

const useInterval = (callback, delay) => {
  const savedCallback = useRef();

  useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);

  useEffect(() => {
    function tick() {
      savedCallback.current && savedCallback.current();
    }
    if (delay !== null && delay > 0) {
      let id = setInterval(tick, delay);
      return () => clearInterval(id);
    } else {
      tick();
    }
  }, [delay]);
};

用法示例:

const [count, setCount] = useState(0);

useInterval(() => {
  setCount(count + 1);
}, 1000);

useDebounce

防抖的 hooks,主要用来限制 API 调用频次或输入时的状态更新,特别是在搜索输入中输入文本时:

import { useState, useEffect, useRef } from "react";

const useDebounce = (callback, delay) => {
  const [debouncing, setDebouncing] = useState(false);
  const savedCallback = useRef<() => void>();

  useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);

  useEffect(() => {
    if (debouncing) {
      return;
    }
    savedCallback.current && savedCallback.current();
    setDebouncing(true);
    setTimeout(() => {
      setDebouncing(false);
    }, delay);
  }, [debouncing, delay]);
};

用法示例:

const [inputValue, setInputValue] = useState("");

useDebounce(() => {
    // do somethings
}, 500);

useThrottle

它是一个用来限制函数的钩子,将每隔指定的时间间隔执行一次。对于防止快速连续触发过多的 API 调用或事件很有用:

import { useState, useEffect, useRef } from "react";

const useThrottle = (callback, limit) => {
  const [throttling, setThrottling] = useState(false);
  const savedCallback = useRef();

  useEffect(() => {
    savedCallback.current = callback;
  }, [callback]);

  useEffect(() => {
    function execute() {
      savedCallback.current && savedCallback.current();
      setThrottling(true);
      setTimeout(() => {
        setThrottling(false);
      }, limit);
    }
    if (!throttling) {
      execute();
    }
  }, [throttling, limit]);
};

用法示例:

const [inputValue, setInputValue] = useState("");

useThrottle(() => {
// do somethings
}, 500);