如何在SWR中实现数据突变及删除后的重新验证?
问题描述
我有两个函数:第一个通过useSWR获取所有引用(quotes)数据、加载状态及mutate函数,代码如下:
// Fetcher and the baseUrl export const baseURL = 'http://localhost:3000/api/'; export const fetcher = (arg: any, ...args: any) => fetch(arg, ...args).then(res => res.json()); // 获取所有引用 export const getAllQuotesArray = () => { const { data: allQuotes, isLoading: allQuotesLoading, mutate: mutateAllQuotes } = useSWR(`${baseURL}/get-quotes`, fetcher); return { allQuotes, allQuotesLoading, mutateAllQuotes }; }
第二个函数用于删除一条记录并返回剩余的对象数组(API路由逻辑一致),代码如下:
// 获取已完成的引用 export const getCompletedQuotes = async () => { try { const response = await fetch(`${baseURL}get-completed-quotes`, { method: 'GET' }); const data = await response.json(); return data; } catch (error) { console.log('', error); } } // 从已完成引用中删除条目 export const deleteFromCompletedQuotes = async (quoteId: string) => { try { await fetch(`${baseURL}delete-quote?id=${quoteId}`, { method: 'DELETE' }); const allRemainingCompletedQuotes = await getCompletedQuotes(); // 尝试重新调用获取函数 getAllQuotesArray(); return allRemainingCompletedQuotes.completedQuotes; } catch (error) { console.log('', error); } }
页面中有两个组件,分别展示已完成引用和所有引用。执行删除操作后,展示所有引用的组件数据未更新,尝试多次使用mutate也无效,请问如何在deleteFromCompletedQuotes函数中实现数据重新验证?
解决方案
核心问题
- 单独调用
getAllQuotesArray()无法触发组件中SWR实例的更新——该函数仅在组件内部调用时才会关联SWR的缓存上下文,独立调用只会生成新的SWR实例,和组件使用的实例无关联。 - 组件中获取到的
mutateAllQuotes未传递给删除函数,导致无法触发目标SWR缓存的重新验证。
具体修改方案
1. 在组件中传递mutate函数到删除方法
在调用删除逻辑的组件里,先从getAllQuotesArray()拿到mutateAllQuotes,再将其作为参数传入deleteFromCompletedQuotes:
// 组件内的调用示例 const { allQuotes, allQuotesLoading, mutateAllQuotes } = getAllQuotesArray(); const handleDelete = async (quoteId: string) => { await deleteFromCompletedQuotes(quoteId, mutateAllQuotes); };
2. 修改删除函数接收并执行mutate
更新deleteFromCompletedQuotes函数,接收mutate参数并调用它触发重新验证:
export const deleteFromCompletedQuotes = async (quoteId: string, mutateAllQuotes: () => Promise<any>) => { try { await fetch(`${baseURL}delete-quote?id=${quoteId}`, { method: 'DELETE' }); const allRemainingCompletedQuotes = await getCompletedQuotes(); // 调用组件传递的mutate函数,触发SWR重新请求最新数据 await mutateAllQuotes(); return allRemainingCompletedQuotes.completedQuotes; } catch (error) { console.log('', error); } }
可选优化:即时更新缓存
如果希望UI立刻更新,无需等待重新请求,可以直接传入更新后的缓存数据,SWR会在后台静默完成重新验证:
// 组件内的优化调用 const handleDelete = async (quoteId: string) => { await deleteFromCompletedQuotes(quoteId, mutateAllQuotes, allQuotes); }; // 对应的删除函数修改 export const deleteFromCompletedQuotes = async (quoteId: string, mutateAllQuotes: (data?: any) => Promise<any>, currentQuotes: any[]) => { try { await fetch(`${baseURL}delete-quote?id=${quoteId}`, { method: 'DELETE' }); const allRemainingCompletedQuotes = await getCompletedQuotes(); // 先更新缓存让UI即时变化,后台自动重新验证确保数据一致性 await mutateAllQuotes(currentQuotes.filter(q => q.id !== quoteId), { revalidate: true }); return allRemainingCompletedQuotes.completedQuotes; } catch (error) { console.log('', error); } }
内容的提问来源于stack exchange,提问作者daniel sas
相关产品推荐
相关产品推荐

