import { useEffect, useRef } from 'react';
|
|
/**
|
* 表单缓存管理器组件 - 仅提供逻辑功能,无UI渲染
|
*
|
* @param {Object} props 组件属性
|
* @param {Object} props.form 表单实例,用于获取表单数据
|
* @param {string} props.cacheKey 缓存的键名
|
* @param {string} props.storageType 存储类型,可选值: 'sessionStorage'|'localStorage',默认为'sessionStorage'
|
* @param {Array} props.fieldsToWatch 需要监听变化的字段列表,如果为空则监听所有字段
|
* @param {Array} props.excludedFields 不应该被自动更新的字段列表,这些字段的值将被保留
|
* @param {number} props.debounceTime 防抖时间(毫秒),默认为500毫秒
|
* @param {Function} props.onCacheUpdated 缓存更新后的回调函数
|
* @returns {null} 不渲染任何UI元素
|
*/
|
const FormCacheManager = ({
|
form,
|
cacheKey = 'form_cache',
|
storageType = 'sessionStorage',
|
fieldsToWatch = [],
|
excludedFields = [],
|
debounceTime = 500,
|
onCacheUpdated
|
}) => {
|
// 使用ref保存定时器
|
const timerRef = useRef(null);
|
|
// 存储表单数据到指定的存储中
|
const saveFormToCache = (formData) => {
|
try {
|
const storage = storageType === 'localStorage' ? localStorage : sessionStorage;
|
|
// 获取现有缓存数据
|
let existingCache = {};
|
try {
|
const existingCacheStr = storage.getItem(cacheKey);
|
if (existingCacheStr) {
|
existingCache = JSON.parse(existingCacheStr);
|
}
|
} catch (error) {
|
console.error('读取现有缓存失败:', error);
|
}
|
|
// 从现有缓存中提取需要保留的字段
|
const preservedFields = {};
|
if (excludedFields.length > 0 && Object.keys(existingCache).length > 0) {
|
excludedFields.forEach(field => {
|
if (existingCache[field] !== undefined) {
|
preservedFields[field] = existingCache[field];
|
}
|
});
|
}
|
|
// 合并新表单数据和需要保留的字段
|
const updatedCache = {
|
...formData,
|
...preservedFields // 保留的字段会覆盖formData中的同名字段
|
};
|
|
// 保存更新后的缓存
|
storage.setItem(cacheKey, JSON.stringify(updatedCache));
|
|
if (onCacheUpdated && typeof onCacheUpdated === 'function') {
|
onCacheUpdated(updatedCache);
|
}
|
|
console.log(`表单数据已缓存到${storageType},键名: ${cacheKey},保留的字段:`, preservedFields);
|
} catch (error) {
|
console.error('缓存表单数据失败:', error);
|
}
|
};
|
|
// 创建防抖函数
|
const debouncedUpdate = () => {
|
if (timerRef.current) clearTimeout(timerRef.current);
|
timerRef.current = setTimeout(() => {
|
if (form) {
|
const currentValues = form.getFieldsValue(fieldsToWatch.length > 0 ? fieldsToWatch : true);
|
saveFormToCache(currentValues);
|
}
|
}, debounceTime);
|
};
|
|
// 设置初始保存
|
useEffect(() => {
|
// 确保form存在
|
if (!form) {
|
console.error('FormCacheManager: form属性是必需的');
|
return;
|
}
|
|
// 给表单一些时间初始化,然后再进行第一次缓存
|
// 这样可以避免覆盖之前的缓存
|
const initTimer = setTimeout(() => {
|
// 初始保存一次表单值
|
debouncedUpdate();
|
}, 500); // 延迟500ms,确保表单已完全初始化
|
|
// 组件卸载时清除定时器
|
return () => {
|
if (timerRef.current) clearTimeout(timerRef.current);
|
clearTimeout(initTimer);
|
};
|
}, [form, cacheKey, storageType, fieldsToWatch, excludedFields, debounceTime, onCacheUpdated]);
|
|
// 监听表单控件的DOM事件
|
useEffect(() => {
|
if (!form || !form.getFieldInstance) return;
|
|
const formNode = document.querySelector('form');
|
if (!formNode) return;
|
|
// 监听表单元素的输入和变化事件
|
const handleFormChange = () => {
|
debouncedUpdate();
|
};
|
|
formNode.addEventListener('input', handleFormChange);
|
formNode.addEventListener('change', handleFormChange);
|
|
return () => {
|
formNode.removeEventListener('input', handleFormChange);
|
formNode.removeEventListener('change', handleFormChange);
|
};
|
}, [form]);
|
|
// 逻辑组件不需要渲染任何内容
|
return null;
|
};
|
|
export default FormCacheManager;
|