Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | 306x 306x 306x 2x 2x 1x 2x 2x 2x 2x 2x 2x 2x 306x 271x 306x | import { useRef, useEffect } from "react";
import { useDefaultValue } from "../form/controlled";
export interface DelayVisibleHookOption {
visible?: boolean;
defaultVisible?: boolean;
onVisibleChange?: (visible: boolean) => void;
}
/**
* @hooks
*
* 延迟设置可见值
*/
export function useDelayVisible(option: DelayVisibleHookOption) {
// 让 visible 属性支持 default
const { value: visible, onChange: onVisibleChange } = useDefaultValue(
{
defaultValue: option.defaultVisible,
value: option.visible,
onChange: option.onVisibleChange,
},
false
);
const lastTaskCancellation = useRef<() => void>(null);
// 延时 timeout 再切换到新的状态,任务保存到 taskRef 中
// 如果有新的变化,清空上次任务,重新开启新任务
const setVisible = (nextVisible: boolean, delay = 0) =>
new Promise<boolean>(resolve => {
if (lastTaskCancellation.current) {
lastTaskCancellation.current();
}
const timer = setTimeout(() => {
onVisibleChange(nextVisible);
resolve(true);
}, delay);
const cancel = () => {
clearTimeout(timer);
resolve(false);
};
lastTaskCancellation.current = cancel;
});
// unmout 的时候无论如何都清除任务
useEffect(
() => () => lastTaskCancellation.current && lastTaskCancellation.current(),
[]
);
return { visible, setVisible };
}
|