Files
yunhaifinance/frontend/src/hooks/useFormGuard.ts
T

53 lines
1.6 KiB
TypeScript
Raw Normal View History

import { useEffect } from 'react';
import { FormInstance } from 'antd';
interface UseFormGuardOptions {
form: FormInstance;
enabled?: boolean;
onSaveDraft?: () => void;
}
/**
* 表单离开拦截 Hook
* - 浏览器刷新/关闭拦截 (beforeunload)
* - 移动端切后台时保存草稿 (visibilitychange + pagehide)
*
* 注意:路由跳转拦截需要在使用组件中手动处理(因为 BrowserRouter 不支持 useBlocker
*/
function useFormGuard(options: UseFormGuardOptions) {
const { form, enabled = true, onSaveDraft } = options;
// 浏览器刷新/关闭拦截
useEffect(() => {
if (!enabled) return;
const handler = (e: BeforeUnloadEvent) => {
if (form.isFieldsTouched()) {
e.preventDefault();
}
};
window.addEventListener('beforeunload', handler);
return () => window.removeEventListener('beforeunload', handler);
}, [form, enabled]);
// 移动端:页面切到后台时保存草稿
useEffect(() => {
if (!enabled || !onSaveDraft) return;
const handler = () => {
if (document.visibilityState === 'hidden' && form.isFieldsTouched()) {
onSaveDraft();
}
};
document.addEventListener('visibilitychange', handler);
const pageHideHandler = () => {
if (form.isFieldsTouched()) onSaveDraft();
};
window.addEventListener('pagehide', pageHideHandler);
return () => {
document.removeEventListener('visibilitychange', handler);
window.removeEventListener('pagehide', pageHideHandler);
};
}, [form, enabled, onSaveDraft]);
}
export default useFormGuard;