feat: add SWR for data fetching with optimistic updates

This commit is contained in:
Developer
2026-03-18 16:16:04 +08:00
parent bd99fc8e81
commit 1f51c330dd
5 changed files with 167 additions and 2 deletions
+54
View File
@@ -0,0 +1,54 @@
import useSWR from 'swr';
import { getRecords, createRecord, updateRecord, deleteRecord } from '../lib/api';
export function useRecords(month, type = 'all') {
const key = month ? ['records', month, type] : null;
const { data, error, isLoading, mutate } = useSWR(
key,
() => getRecords(month, type),
{
revalidateOnFocus: false,
dedupingInterval: 5000,
}
);
// 乐观更新:添加记录
const addRecord = async (recordData) => {
const newRecord = await createRecord(recordData);
mutate(
(current) => (current ? [...current, newRecord] : [newRecord]),
{ revalidate: false }
);
return newRecord;
};
// 乐观更新:更新记录
const editRecord = async (id, recordData) => {
await updateRecord(id, recordData);
mutate(
(current) =>
current?.map((r) => (r.id === id ? { ...r, ...recordData } : r)),
{ revalidate: false }
);
};
// 乐观更新:删除记录
const removeRecord = async (id) => {
await deleteRecord(id);
mutate(
(current) => current?.filter((r) => r.id !== id),
{ revalidate: false }
);
};
return {
records: data || [],
isLoading,
error,
mutate,
addRecord,
editRecord,
removeRecord,
};
}
+57
View File
@@ -0,0 +1,57 @@
import useSWR from 'swr';
import { getStats, getTrendStats, getCategoryStats } from '../lib/api';
export function useStats(month) {
const key = month ? ['stats', month] : null;
const { data, error, isLoading, mutate } = useSWR(
key,
() => getStats(month),
{
revalidateOnFocus: false,
}
);
return {
stats: data || { income: 0, expense: 0, balance: 0 },
isLoading,
error,
mutate,
};
}
export function useTrendStats(period = 'month', month) {
const key = ['trend', period, month];
const { data, error, isLoading } = useSWR(
key,
() => getTrendStats(period, month),
{
revalidateOnFocus: false,
}
);
return {
trend: data || [],
isLoading,
error,
};
}
export function useCategoryStats(month, type = 'all') {
const key = ['categoryStats', month, type];
const { data, error, isLoading } = useSWR(
key,
() => getCategoryStats(month, type),
{
revalidateOnFocus: false,
}
);
return {
categories: data || [],
isLoading,
error,
};
}