Open
Description
功能介绍
usePageCacheState 用于页面级别的缓存处理方案,通过缓存记录当前页面完整状态,一般会缓存较多数据。
支持的功能:
- 支持可存储多条数据。默认缓存一条数据,或者传入subKey,根据subKey作为主键缓存多条数据。
- 支持设置缓存最大数量
- 内置记录数据创建时间、更新时间。支持单条数据的过期时间设置,可指定根据据[创建时间 | 更新时间]计算是否过期,并自动清空过期数据。
- 支持读写时,带上缓存数据版本号。缓存数据结构破坏性不兼容变更时,升级版本号,舍弃旧版本缓存数据,可简单解决旧缓存数据不兼容问题。
使用场景
此 hook 常用于提升用户操作体验的场景。比如用户在【创建xx表单页】需要填写表单项较多,经常会主动/不小心退出当前页面,希望同个登录用户再次进入【创建xx表单页】可以恢复刚填写的内容。而其他登录用户进入【创建xx表单页】是重新填写,不读取其他用户的缓存。同时可设置缓存最大数量防止浏览器本地内存溢出问题。可设置缓存过期时间,不回填过于老旧的操作缓存等。
接口设计
/** 单条记录的存储的数据类型 */
type UnitStorageState<T> = {
subKey: Exclude<Options<T>['subKey'], undefined>;
createTime: number;
createTimeFormat: string;
updateTime: number;
updateTimeFormat: string;
/** 用户数据 */
data?: T;
};
interface Options<T> {
/** 缓存类型 */
storageType?: StorageType;
/** 二级key。用于区分同个页面,不同用户的缓存 */
subKey?: string;
/** 过期时间 单位秒 s */
expire?: number;
/** 用于计算过期时间取值属性 */
expireTimeProp?: ExpireTimeProp;
/** 最大数量 */
maxCount?: number;
/** 缓存版本号 */
version?: number | string;
}
export type StorageType = 'localStorage' | 'sessionStorage';
export type ExpireTimeProp = 'createTime' | 'updateTime';
export type SetUnitDataState<S> = S | ((prevState?: S) => S);
/** 单条记录的存储的数据类型 */
type UnitStorageState<T> = {
subKey: Exclude<Options<T>['tsubKey'], undefined>;
createTime: number;
createTimeFormat: string;
updateTime: number;
updateTimeFormat: string;
/** 用户数据 */
data?: T;
};
interface Options<T> {
/** 缓存类型 */
storageType?: StorageType;
/** 二级key。用于区分同个页面,不同用户的缓存 */
subKey?: string;
/** 过期时间 单位秒 s */
expire?: number;
/** 用于计算过期时间取值属性 */
expireTimeProp?: ExpireTimeProp;
/** 最大数量 */
maxCount?: number;
/** 缓存版本号 */
version?: number | string;
}
usePageCacheState<T>(key: string, options?: Options<T>): [unitData: T | undefined, (unitData: SetUnitDataState<T>) => void, {
delete: (subKey?: string | undefined) => void;
storageState: UnitStorageState<T>[] | undefined;
setStorageState: (value?: UnitStorageState<T>[] | IFuncUpdater<UnitStorageState<T>[] | undefined> | undefined) => void
}]
使用示例
const [name, setName] = useState<string>();
const [age, setAge] = useState<number>();
const [pageCache, setPageCache, { delete: deletePageCache, storageState }] = usePageCacheState<{ props: any; name?: string; age?: number }>(
'CREATE_PAGE_CACHE_KEY',
{
subKey: userId,
maxCount: 20,
expire: 3 * 24 * 3600,
version: 'f1308000',
}
);
/** set to Storage when deps mutation */
useEffect(() => {
setPageCache({
props,
name,
age,
// others data should be cached...
});
}, [props, name, age]);
/** initial state from cache data */
useEffect(() => {
if (pageCache) {
const { name, age } = pageCache;
setName(name);
setAge(age);
// others cache data sync to state
}
}, []);
return (
<form
onSubmit={() => {
// submit success
deletePageCache();
}}
>
<label>姓名:</label>
<input value={name} onChange={e => setName(e.target.value)}></input>
<label>年龄:</label>
<input value={age} onChange={e => setAge(Number(e.target.value))}></input>
</form>
);