在 SWR 中使用 mutate 重新验证数据 - 我应该使用哪个?

Posted

技术标签:

【中文标题】在 SWR 中使用 mutate 重新验证数据 - 我应该使用哪个?【英文标题】:Revalidating data using mutate in SWR - Which should I use? 【发布时间】:2021-01-22 11:28:53 【问题描述】:

在我的应用中,每次用户创建新专辑时,发布请求响应都会以更新的专辑列表列表进行响应。

为了提供更好的用户体验,我希望用户无需刷新页面即可看到应用中的新内容。

我知道 SWR 变异的存在,但到目前为止,我无法让它发挥作用。

我尝试在我的钩子中设置一个 1000 毫秒 refreshInterval,但我想知道如何使用 mutate 来做到这一点。这是我尝试过的:

SWR 钩子

const fetcher = async (url: string, param: string) => 
    const res = await fetch(url + param);
    
   return res.json();
;


const  data, error  = useSWR(
 ["/api/albums/list?id=", appUser.id],
  (url, params) => fetcher(url, params)
);

createAlbum 函数内部:

const data = await response.json();

mutate("/api/albums/list", data.newAlbums, false);

我很乐意得到一些反馈。

【问题讨论】:

【参考方案1】:

你可以这样做

const  data, mutate, error  = useSWR(
 ["/api/albums/list?id=", appUser.id],
  (url, params) => fetcher(url, params)
);

要重新加载 swr 缓存,只需调用 mutate();

此 mutate 指的是您的专辑获取调用。 Swr 会自动重新获取您的数据。

【讨论】:

revalidate() 是刷新数据的规范调用。 我在swr github.com/vercel/swr#manually-revalidate 中看不到任何revalidate() 函数。 它显然是无证的,但它就在那里。 github.com/vercel/swr/blob/…【参考方案2】:

你的代码几乎是正确的,问题在于SWRinternally hashes the keys used for queries/mutation。所以mutate函数使用的key根本没有在缓存中注册。

使用全局变异

要使用由swr 直接导出的mutate 函数来解决此问题,只需将相同的密钥传递给useSWRmutate

mutate(["/api/albums/list?id=", appUser.id]);

这将使散列键的缓存无效。从原始钩子中检索到的数据将过时,因此将被再次获取。

使用绑定变异

另一种选择是利用绑定到 swr 密钥的 mutate 函数。

const  data, error, mutate  = useSWR(
   ["/api/albums/list?id=", appUser.id],
   (url, params) => fetcher(url, params)
);

/*
 * Now you can just call `mutate()` without specifying `key` argument
 */

文档:https://github.com/vercel/swr#bound-mutate

指定刷新间隔

正如您所说,为了完整起见,另一种选择是设置 refreshInterval 属性的值。在需要时强制重新获取:

const  data, error  = useSWR(
   ["/api/albums/list?id=", appUser.id],
   (url, params) => fetcher(url, params),
   
     refreshInterval: 1000, 
   
);

【讨论】:

完美答案,满足了我的所有需求:)。还有一件事,你可以看到我的 fetcher 有 (url, params) 作为参数。我想像这样传递一个参数(...args),但我得到一个打字稿错误。你不需要回答这个问题,我已经投票并接受了,但我想知道,因为我已经对此提出了问题,但我无法得到回复【参考方案3】:

您的 UI 在 mutate 后没有刷新的原因是传递给 mutate()useSWR() 的第一个参数不匹配。

第一个参数本质上是一个唯一键,SWR 使用它来将钩子与变异关联起来。更新您的 mutate 调用以使用与钩子相同的密钥,它应该可以解决您的问题。

mutate("/api/albums/list?id=", data.newAlbums, false);

【讨论】:

以上是关于在 SWR 中使用 mutate 重新验证数据 - 我应该使用哪个?的主要内容,如果未能解决你的问题,请参考以下文章

SWR 根据下拉列表中的选定值获取数据

带有graphql-request的SWR如何在swr中添加变量?

Next.js 使用 SWR 和 axios

在Tidyverse中使用“mutate_at”在多个变量中重新编码相同的因子水平值

如何使用 swr 编写测试

socket.io vs swr 用于更新实时内容