- 前端
- 缓存
【免费下载链接】swr
React Hooks for Data Fetching
导读
本文基于 SWR 仓库中的 global-fetcher 示例,讲解如何借助SWRConfigProvider 在应用顶层集中配置fetcher,从而避免在每个useSWRHook 调用中重复传入请求函数。读完本文,你将掌握全局 Fetcher 的配置方式、底层实现原理,以及如何在 Next.js 的_app.js中落地这一方案。
示例定位:Global Fetcher
examples/global-fetcher/README.md 明确说明了该示例的核心思想:
Use the
SWRConfigprovider to set up the fetcher globally instead of a per-hook call.
即:使用SWRConfigProvider 全局设置 fetcher,而不是在每个 Hook 调用中逐个传入。这一做法可以让所有useSWR调用共享同一个请求函数,显著减少重复代码。
该示例基于 Next.js 构建(依赖next、react、react-dom、swr,见 examples/global-fetcher/package.json),页面结构如下:
- pages/_app.js:在应用入口通过
SWRConfig全局注入 fetcher; - libs/fetch.js:自定义的全局 fetcher 实现;
- pages/index.js:首页列表,展示 Trending Projects;
- pages/[user]/[repo].js:仓库详情页,展示 forks/stars/watchers 数据;
- pages/api/data.js:模拟延迟的 API 路由。
一、快速启动:下载示例并运行
按照 README 提供的步骤,可以先下载示例到本地:
curl https://codeload.github.com/vercel/swr/tar.gz/main | tar -xz --strip=2 swr-main/examples/global-fetcher cd global-fetcher然后安装依赖并启动开发服务器(支持 yarn 与 npm 两种方式):
yarn yarn dev # 或 npm install npm run devpackage.json中还提供了生产构建与启动命令:npm run build(Next.js 构建)与npm run start(启动生产服务器)。
二、核心实现:SWRConfig 全局配置
2.1 全局注入 fetcher
在 pages/_app.js 中,示例通过 Next.js 的自定义 App 组件,用SWRConfig包裹整个应用:
import React from 'react' import App from 'next/app' import { SWRConfig } from 'swr' import fetch from '../libs/fetch.js'; export default class MyApp extends App { render() { const { Component, pageProps } = this.props return <SWRConfig value={{ fetcher: fetch }} > <Component {...pageProps} /> </SWRConfig> } }关键点:
SWRConfig的value属性接受一个配置对象,其中fetcher字段指定全局请求函数;- 包裹之后,应用内所有
useSWR调用在未显式传 fetcher 时,都会自动使用这个全局 fetcher; - 由于
_app.js是 Next.js 所有页面的公共入口,因此这一配置对全部页面生效。
2.2 自定义 fetcher 的实现
全局 fetcher 定义在 libs/fetch.js:
export default async function fetcher(...args) { const res = await fetch(...args) return res.json() }它接受任意参数(...args),透传给原生fetch,并将响应解析为 JSON。这样,页面中调用useSWR('/api/data')时,SWR 会把 key(即'/api/data')作为参数传给 fetcher,自动完成请求与 JSON 解析。
2.3 页面中使用全局配置
在 pages/index.js 中,useSWR只传入 key,无需再写 fetcher:
import useSWR from 'swr' export default function Index() { const { data } = useSWR('/api/data') // ... }详情页 pages/[user]/[repo].js 同样如此,只需在 key 中带上查询参数:
const id = typeof window !== 'undefined' ? window.location.pathname.slice(1) : '' const { data } = useSWR('/api/data?id=' + id)这说明:一旦配置了全局 fetcher,所有useSWR调用都可以省略第二个参数,代码更加简洁统一。
三、底层原理:SWRConfig 如何工作
3.1 配置上下文与合并
从源码看,SWRConfig的公开入口定义在 src/index/config.ts,它从_internal导入并重新导出SWRConfig。
真正实现位于 src/_internal/utils/config-context.ts:
- 模块创建了
SWRConfigContext = createContext<Partial<FullConfiguration>>({}),用于在 React 组件树中传递配置; SWRConfig组件通过useContext(SWRConfigContext)读取父级配置,并通过mergeConfigs(parentConfig, config)将父级配置与自身配置合并,形成扩展后的配置;- 配置支持函数形式:
value可以传入(parentConfig) => config这样的函数,useMemo会在依赖变化时重新计算(见源码 config-context.ts)。
因此,全局 fetcher 本质上是通过 React Context 在组件树顶层注入fetcher,任意深层的useSWR都能通过上下文读取到它。
3.2 fetcher 的解析顺序
在useSWR的参数规范化过程中,src/_internal/utils/normalize-args.ts 会区分三种调用形式:
export const normalize = <KeyType = Key, Data = any>( args: | [KeyType] | [KeyType, Fetcher<Data> | null] | [KeyType, SWRConfiguration | undefined] | [KeyType, Fetcher<Data> | null, SWRConfiguration | undefined] ): [KeyType, Fetcher<Data> | null, Partial<SWRConfiguration<Data>>] => { return isFunction(args[1]) ? [args[0], args[1], args[2] || {}] : [args[0], null, (args[1] === null ? args[2] : args[1]) || {}] }即:当第二个参数是函数时,它被当作 fetcher;否则按配置对象处理。当useSWR只传入 key 时,fetcher 为空,SWR 会回退到配置上下文中解析出的全局 fetcher。这正好解释了 global-fetcher 示例中“省略 fetcher 也能工作”的原因——全局配置在参数解析后作为兜底生效。
3.3 可继承与覆盖
由于SWRConfig支持嵌套且会与父级配置合并,你可以在全局设置一个默认 fetcher,然后在局部(如某个页面或组件内)用另一个SWRConfig覆盖 fetcher,实现灵活的分层配置。这是mergeConfigs合并逻辑带来的能力。
四、深入理解:配置合并的核心逻辑
SWRConfig的合并行为由 src/_internal/utils/merge-config.ts 支撑(mergeConfigs函数在此实现)。其设计要点:
- 子级配置会覆盖父级同名配置项;
- 这种覆盖机制不仅适用于
fetcher,也同样适用于revalidateOnFocus、suspense、refreshInterval、dedupingInterval等其他 SWR 配置项。
从类型定义看,SWRConfigValue与FullConfiguration定义在 src/_internal/types.ts 中,其中fetcher的类型为Fetcher<any> | null,默认值在全局默认配置中为null。这意味着如果不配置全局 fetcher,useSWR调用就必须显式传入 fetcher,否则请求不会执行。
五、测试验证
SWR 仓库针对全局配置与上下文行为编写了测试,例如 test/use-swr-config.test.tsx 与 test/use-swr-context-config.test.tsx)实现;useSWR参数规范化(normalize-args.ts)在未传入 fetcher 时回退到全局配置。
- 扩展能力:嵌套
SWRConfig支持局部覆盖,可针对特定页面或组件调整请求行为。
如需查看更多 SWR 用法,可继续阅读仓库中其他示例,例如 examples/basic、examples/global-fetcher 同级的 examples/infinite 等;更完整的配置项说明可参考 src/_internal/types.ts。
- 前端
- 缓存
【免费下载链接】swr
React Hooks for Data Fetching
相关推荐
5 分钟把 VSDX 搬进 drawio:跨平台 Visio 转换实操
5 分钟把 VSDX 搬进 drawio:跨平台 Visio 转换实操 一个 .vsdx 送过来,本机却装不了 Visio。drawio 桌面版可以直接导入它,
桌面应用图形学Nextra 文档站中的 SWRConfig 全局配置实战:统一 SWR 数据请求行为
Nextra 文档站中的 SWRConfig 全局配置实战:统一 SWR 数据请求行为 导读 本文以 Nextra 仓库中的 SWR 官方文档站( exampl
前端文档/教程SWR 全局 Suspense 模式实战:用 SWRConfig 一处配置、全站享受 React Suspense
SWR 全局 Suspense 模式实战:用 SWRConfig 一处配置、全站享受 React Suspense 导读 本文基于 SWR 官方示例 suspe
前端缓存
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考