宣布 SWR 1.0
大约两年前,我们开源 (在新标签页中打开) SWR,这个人们喜爱的微型数据获取 React 库。今天,我们迎来了另一个里程碑:SWR 的 1.0 版本!
新增功能
更小尺寸
性能 是 SWR 最重要的功能之一。在 1.0 版本中,我们大幅减小了库的体积,但没有删除任何现有功能。
- 核心体积缩小 41%(压缩后缩小 24%,仅 3.9 kB)
- 包安装尺寸缩小 52%
- 改进了树状抖动
使库变得轻量级的理由有很多:您的应用程序将拥有更小的包,更精简的运行时,以及更小的 node_modules
目录。
我们还改进了包的捆绑,现在支持路径导入
import useSWR from 'swr'
import useSWRInfinite from 'swr/infinite'
如果您没有使用 useSWRInfinite
,它将不会包含在您的应用程序中。
回退数据
在 1.0 版本中,有一个新的 fallback
选项,您可以提供任何预取的数据作为所有具有特定键的 SWR hook 的初始值
<SWRConfig value={{
fallback: {
'/api/user': { name: 'Bob', ... },
'/api/items': ...,
...
}
}}>
<App/>
</SWRConfig>
这对 SSG、SSR 和用于测试的数据模拟等场景非常有用。查看文档 Next.js SSG 和 SSR 了解更多详细信息。
为了提高一致性并避免混淆,旧的 initialData
现已重命名为 fallbackData
,它仍然为给定的 hook 提供单个回退值。
不可变模式
有时您希望将资源标记为不可变,如果它永远不会改变。最好为它禁用自动重新验证,并且只执行一次请求。现在有一个辅助 hook 使此操作更容易
import useSWRImmutable from 'swr/immutable'
// ...
useSWRImmutable(key, fetcher, options)
它与 useSWR
hook 具有完全相同的 API,但它永远不会在标签焦点或网络恢复时重新验证。还有一个新的选项 revalidateIfStale
,您可以使用它来精确地控制行为。更多信息可以在 此处 找到。
自定义缓存提供程序
默认情况下,SWR 使用单个全局缓存来存储所有数据。在 1.0 版本中,您可以使用新的 provider
选项对其进行自定义
<SWRConfig value={{
provider: () => myCache
}}>
<App/>
</SWRConfig>
您可以使用此新功能完成许多强大的操作。我们在这里有一些示例:使用 RegEx 变异多个键、基于 LocalStorage 的持久缓存、在测试用例之间重置缓存。
此新的缓存提供程序 API 与 React 18 的并发渲染也更加兼容。如果您要添加缓存提供程序,请确保使用从 useSWRConfig()
返回的全局 mutate
函数。
您可以阅读文档 缓存提供程序 了解更多详细信息。
useSWRConfig()
有一个新的 Hook API 用于返回所有全局配置,包括当前缓存提供程序和全局 mutate
函数
import { useSWRConfig } from 'swr'
function Foo () {
const { refreshInterval, cache, mutate, ...restConfig } = useSWRConfig()
// ...
}
更多信息可以在 此处 找到。
中间件
SWR 中间件为您提供了一种在 SWR hook 之上构建和重用抽象的新方法
<SWRConfig value={{ use: [...middleware] }}>
// ... or directly in `useSWR`:
useSWR(key, fetcher, { use: [...middleware] })
许多新想法都可以使用此功能来实现,我们已经构建了一些示例:请求记录器、更改键时保留之前的结果 以及 序列化对象键。
查看 中间件 API 了解更多详细信息。
改进和更好的测试覆盖率
自 0.x 版本以来,我们已经进行了数百项小改进和错误修复。SWR 现在拥有 157 个测试,涵盖了数据获取中的大多数边缘情况。阅读 更改日志 (在新标签页中打开) 了解更多详细信息。
文档翻译
感谢我们的 贡献者 (在新标签页中打开) 和 Nextra 的 i18n 功能 (在新标签页中打开),我们现在提供六种语言的 SWR 文档。
迁移指南
更新 useSWRInfinite
导入
useSWRInfinite
需要从 swr/infinite
导入
- import { useSWRInfinite } from 'swr'
+ import useSWRInfinite from 'swr/infinite'
如果你正在使用对应的类型,也更新导入路径
- import { SWRInfiniteConfiguration, SWRInfiniteResponse } from 'swr'
+ import { SWRInfiniteConfiguration, SWRInfiniteResponse } from 'swr/infinite'
将 revalidate
改为 mutate
useSWR
不再返回 revalidate
方法,改为使用 mutate
- const { revalidate } = useSWR(key, fetcher, options)
+ const { mutate } = useSWR(key, fetcher, options)
// ...
- revalidate()
+ mutate()
将 initialData
重命名为 fallbackData
- useSWR(key, fetcher, { initialData: ... })
+ useSWR(key, fetcher, { fallbackData: ... })
不再有默认的 Fetcher
SWR 不再提供默认的 fetcher(一个将数据解析为 JSON 的 fetch
调用)。迁移更改的最简单方法是使用 <SWRConfig>
组件
<SWRConfig value={{ fetcher: (url) => fetch(url).then(res => res.json()) }}>
<App/>
</SWRConfig>
// ... or
useSWR(key, (url) => fetch(url).then(res => res.json()))
建议使用 Hook 返回的 mutate
这**不是**一个重大更改,但我们现在**建议**始终使用 mutate
,它由 useSWRConfig
hook 返回
- import { mutate } from 'swr'
+ import { useSWRConfig } from 'swr'
function Foo () {
+ const { mutate } = useSWRConfig()
return <button onClick={() => mutate('key')}>
Mutate Key
</button>
}
如果你没有使用缓存提供程序,当前的全局导入 import { mutate } from 'swr'
仍然有效。
重命名的类型
如果你正在使用 TypeScript,以下类型名称已更改以保持一致性
0.x (已弃用) | 1.0 | 注意 |
---|---|---|
ConfigInterface | SWRConfiguration | |
keyInterface | Key | |
responseInterface | SWRResponse | |
RevalidateOptionInterface | RevalidatorOptions | |
revalidateType | Revalidator | |
SWRInfiniteResponseInterface | SWRInfiniteResponse | 已移至 swr/infinite |
SWRInfiniteConfigInterface | SWRInfiniteConfiguration | 已移至 swr/infinite |
Beta 版和非官方功能用户
如果你正在使用 SWR 的 beta 版,或者正在使用任何未公开的 API,请注意以下更改
import { cache } from 'swr'
已移除;请改用新的useSWRConfig
API。import { createCache } from 'swr'
已移除;请改用新的 缓存提供程序 API。revalidateWhenStale
已重命名为revalidateIfStale
。middlewares
已重命名为use
。
变更日志
阅读完整的变更日志 在 GitHub 上 (在新标签页中打开)。
下一步
在未来的版本中,我们将继续改进库,同时保持稳定性。我们也致力于拥抱未来的 React 版本,因为 1.0 中的几个新功能和改进已经在为此做准备。此外,我们还在开发新功能,以改善在 React 中进行数据获取的体验以及使用此库的体验。
如果你对本版本有任何反馈,请 告知我们 (在新标签页中打开)。
感谢你!
特别感谢 小林 徹 (在新标签页中打开) 和 徐亦轩 (在新标签页中打开) 对库的贡献,以及 Paco Coursey (在新标签页中打开)、uttk (在新标签页中打开)、塩谷 智宏 (在新标签页中打开)、Markoz Peña (在新标签页中打开)、崔瑟琪 (在新标签页中打开)、方路 (在新标签页中打开)、Valentin Politov (在新标签页中打开) 对翻译和文档的贡献。没有他们,这个版本不可能实现。
我们还要感谢整个社区,我们的 110 位贡献者 (在新标签页中打开)(+ 45 位文档贡献者 (在新标签页中打开))以及所有帮助我们并提供反馈的人!