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(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 }; }