如何写
自定义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;
};