useDebounce
import { useEffect, useRef, useState } from "react";
const useDebounce = <V>(value: V, delay: number) => {
const [debouncedValue, setDebouncedValue] = useState(value);
const timerRef = useRef<NodeJS.Timeout | undefined>(undefined);
useEffect(() => {
if (timerRef.current) {
clearTimeout(timerRef.current);
}
timerRef.current = setTimeout(() => {
setDebouncedValue(value);
}, delay);
return () => {
clearTimeout(timerRef.current);
};
}, [value, delay, timerRef.current]);
return debouncedValue;
};
export default useDebounce;
const useDebounce = <V>(value: V, delay: number) => {
const [debouncedValue, setDebouncedValue] = useState<V>(value);
useEffect(() => {
const timeout = setTimeout(() => setDebouncedValue(value), delay);
return () => clearTimeout(timeout);
}, [delay, value]);
return debouncedValue;
};
useOffsetTop
import { useEffect, useRef, useState } from 'react';
import { useFuncDebounce, useMount } from '.';
interface OffsetProps {
extraHeight?: number;
id?: string;
patch?: number;
}
interface DomAttr {
top: number;
bottom: number;
height: number;
left: number;
right: number;
width: number;
x: number;
y: number;
}
export const useOffsetTop = ({ extraHeight = 80, id, patch = 0 }: OffsetProps = {}) => {
const tableRef = useRef<HTMLDivElement>(null);
const [height, setHeight] = useState<number>(0);
const onSizeChange = function () {
return saveHeightChange();
};
const debouncedCallback = useFuncDebounce(onSizeChange, 500);
const getOffsetTop = () => {
if (tableRef.current && tableRef.current instanceof HTMLDivElement) {
const { top } = tableRef.current?.getBoundingClientRect() as DomAttr;
id ? tableRef.current.setAttribute('data-key', id) : null;
const tableHeight = document.body.clientHeight - top - extraHeight - patch;
return tableHeight;
}
return 0;
};
const exportHeight = () => {
return height;
};
const saveHeightChange = () => {
return setHeight(() => {
const height = getOffsetTop() >= 0 ? getOffsetTop() : 0;
return height;
});
};
addEventListener('resize', debouncedCallback);
useMount(
() => {
saveHeightChange();
},
() => {
removeEventListener('resize', debouncedCallback);
},
);
useEffect(() => {
saveHeightChange();
});
return [tableRef, exportHeight] as const;
};
import { useMemo, useRef, useState } from 'react';
import { useMount } from '.';
interface OffsetProps {
extraHeight?: number;
id?: string;
}
interface DomAttr {
top: number;
bottom: number;
height: number;
left: number;
right: number;
width: number;
x: number;
y: number;
}
const BODYELEMENT = 'body';
const body = document.getElementsByTagName(BODYELEMENT)[0];
export const useOffsetTop = ({ extraHeight = 80, id }: OffsetProps = {}) => {
const tableRef = useRef<HTMLDivElement>(null);
const [height, setHeight] = useState<number>(0);
const getOffsetTop = () => {
if (tableRef.current && tableRef.current instanceof HTMLDivElement) {
const { top } = tableRef.current?.getBoundingClientRect() as DomAttr;
id ? tableRef.current.setAttribute('data-key', id) : null;
const tableHeight = document.body.clientHeight - top - extraHeight;
return tableHeight;
}
return 0;
};
const exportHeight = () => {
return height;
};
const saveHeightChange = () => {
return setHeight(() => {
const height = getOffsetTop() >= 0 ? getOffsetTop() : 0;
return height;
});
};
const resizeObserver = new ResizeObserver(function (entry) {
saveHeightChange();
});
useMemo(() => {
resizeObserver.observe(body);
}, [body, resizeObserver.observe]);
useMount(
() => {
saveHeightChange();
},
() => {
resizeObserver.disconnect();
},
);
return [tableRef, exportHeight] as const;
};
useFuncDebounce
import { useEffect, useRef } from 'react';
import _ from 'lodash';
export const useFuncDebounce = function () {
const timerRef = useRef<NodeJS.Timeout | undefined>(undefined);
function debouncedCallback<T extends Function, K extends unknown>(callback: T, delay: number) {
return function (object: K, ...args: unknown[]) {
if (timerRef.current) clearTimeout(timerRef.current);
timerRef.current = setTimeout(() => {
if (_.isObject(object)) callback.apply(object, args);
else callback(object, ...args);
}, delay);
};
}
useEffect(function () {
return function () {
clearTimeout(timerRef.current);
};
}, []);
return debouncedCallback;
};
useData
import { useState } from 'react';
import _ from 'lodash';
const DATALAYERS = 'data.items';
const TOTALLAYERS = 'data.meta.total';
const MESSAGE = '请求的返回体为空!';
export const useData = <T>() => {
const [data, setData] = useState<T>();
const [total, setTotal] = useState<number>(0);
const setDataAuxiliary = (res: any, path?: string) => {
if (res) setData(_.get(res, path ? path : DATALAYERS, []));
else throw new Error(MESSAGE);
};
const setTotalAuxiliary = (res: any, path?: string) => {
if (res) setTotal(_.get(res, path ? path : TOTALLAYERS, 0));
else throw new Error(MESSAGE);
};
return [data, setDataAuxiliary, total, setTotalAuxiliary] as const;
};
useBoolean
import { useState } from 'react';
export const useBoolean = (initValue: boolean = false) => {
const [value, setValue] = useState(initValue);
const on = () => {
setValue(true);
};
const off = () => {
setValue(false);
};
const toggle = () => {
setValue(!value);
};
return [value, toggle, on, off] as const;
};