自定义hooks

556 阅读1分钟

如何写

自定义hooks返回值设计

结果: 返回三个以内用数组,返回三个以上用对象

原因: 如果返回数组的话,可以按照顺序解构。在用到多个hooks的时候,就可以直接修改hooks返回对应的值, 返回对象,使用多次hooks的时候,解构的时候必须要和hooks返回的值一样,然后再进行重命名

懒加载

简单实现:

1.使用scroll监听 2.使用 IntersectionObserver来判断在不在可视区 www.ruanyifeng.com/blog/2016/1…

这里使用第一种

import { useEffect, useRef, useState, useCallback } from 'react';

export const useLazyLoad = () => {
  const lazyRef = useRef<any>(null);
  
  const initScrollTop = document.documentElement.scrollTop;
  
  const [scrollNum, setScrollNum] = useState(initScrollTop ?? 0);
  
  const handleGetScrollTop = useCallback(() => {
    const scrollTop = document.documentElement.scrollTop;
    // 优化scroll 可以设置节流
    setScrollNum(scrollTop);
  }, []);

  useEffect(() => {
    document.addEventListener('scroll', handleGetScrollTop);
    return () => {
      document.removeEventListener('scroll', handleGetScrollTop);
    };
  }, []);

  useEffect(() => {
    const el = lazyRef.current;
    if (el) {
      const boundingTop = el.getBoundingClientRect();
      const { clientHeight } = document.documentElement;
      const sourceSrc = el.getAttribute('data-src');
      // console.log({ scrollNum, boundingTop, clientHeight }, '----->滚动高度,元素距离顶部, 可视区高度');
      // 当前可视区域高度 >= 图片到视口的高度
      if (clientHeight >= boundingTop.top) {
        el.src = sourceSrc;
        document.removeEventListener('scroll', handleGetScrollTop);
      }
    }
  }, [scrollNum]);
  
  return [lazyRef] as const;
  
};


使用方法 使用hooks获取到ref, 然后给需要加载图片的地方绑定ref, 注意:图片 data-src设置真实图片地址

const [lazyRef1] = useLazyLoad();
<img ref={lazyRef1} data-src="/image/img1.png" alt="" />;

防抖

节流

打开弹窗

export const useDrawer = (props: boolean) => {
  const [visible, setVisible] = useState(props);

  const open = useCallback(() => {
    setVisible(true);
  }, []);

  const close = useCallback(() => {
    setVisible(false);
  }, []);

  return [visible, open, close] as const;
};

设置boolean

export const useBoolean = (props: boolean) => {
  const [state, setState] = useState(props);

  const setTrue = useCallback(() => {
    setState(true);
  }, []);

  const setFalse = useCallback(() => {
    setState(false);
  }, []);

  const toggle = useCallback(() => {
    setState((prevState) => !prevState);
  }, []);

  return [state, toggle, setTrue, setFalse] as const;
};