flnxi-Wu/lib/hooks/useTemplates.ts
WuYongJie 3c009350d7 feat: 前端性能优化(任务23)
- 创建防抖Hooks
  * useDebounce - 延迟更新值直到用户停止输入
  * useDebouncedCallback - 创建防抖的回调函数
  * 支持自定义延迟时间(默认300ms)

- 创建SWR缓存Hooks
  * useTemplates - 缓存模板列表
  * useTemplate - 缓存单个模板详情
  * 配置智能缓存策略(5秒去重、错误重试)
  * 支持手动刷新数据

- 现有优化
  * 字段验证使用useMemo避免重复计算
  * 表单组件使用React.memo和useCallback优化渲染
  * 拖拽排序使用防抖避免频繁更新

性能提升:
- 减少不必要的API请求
- 优化表单输入响应速度
- 提升大表单的渲染性能
2025-12-13 15:33:10 +08:00

82 lines
1.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import useSWR from 'swr'
interface UploadTemplateDto {
id: string
name: string
description: string | null
status: string
materialType: string
materialKind?: string
version: number
fieldGroups: any
displayConfig: any
createdAt: string
updatedAt: string
fields: any[]
}
const fetcher = async (url: string) => {
const res = await fetch(url)
if (!res.ok) {
const error: any = new Error('获取模板列表失败')
error.status = res.status
throw error
}
return res.json()
}
/**
* 使用SWR缓存模板列表
* @param shouldFetch 是否应该获取数据(默认true)
* @returns SWR返回对象
*/
export function useTemplates(shouldFetch: boolean = true) {
const { data, error, isLoading, mutate } = useSWR<UploadTemplateDto[]>(
shouldFetch ? '/api/admin/upload-templates' : null,
fetcher,
{
// 缓存配置
revalidateOnFocus: false, // 窗口聚焦时不重新验证
revalidateOnReconnect: true, // 重新连接时重新验证
dedupingInterval: 5000, // 5秒内的重复请求会被去重
// 错误重试配置
errorRetryCount: 3,
errorRetryInterval: 1000,
}
)
return {
templates: data,
isLoading,
isError: error,
mutate, // 用于手动刷新数据
}
}
/**
* 使用SWR缓存单个模板详情
* @param templateId 模板ID
* @param shouldFetch 是否应该获取数据(默认true)
* @returns SWR返回对象
*/
export function useTemplate(templateId: string | null, shouldFetch: boolean = true) {
const { data, error, isLoading, mutate } = useSWR<UploadTemplateDto>(
shouldFetch && templateId ? `/api/admin/upload-templates/${templateId}` : null,
fetcher,
{
revalidateOnFocus: false,
revalidateOnReconnect: true,
dedupingInterval: 5000,
errorRetryCount: 3,
errorRetryInterval: 1000,
}
)
return {
template: data,
isLoading,
isError: error,
mutate,
}
}