拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

SWR 全局 Fetcher 配置指南:用 SWRConfig Provider 统一管理数据请求

SWR 全局 Fetcher 配置指南:用 SWRConfig Provider 统一管理数据请求
  • 前端
  • 缓存

【免费下载链接】swr

React Hooks for Data Fetching

项目地址:https://gitcode.com/gh_mirrors/sw/swr
点击查看免费下载

导读

本文基于 SWR 仓库中的 global-fetcher 示例,讲解如何借助SWRConfigProvider 在应用顶层集中配置fetcher,从而避免在每个useSWRHook 调用中重复传入请求函数。读完本文,你将掌握全局 Fetcher 的配置方式、底层实现原理,以及如何在 Next.js 的_app.js中落地这一方案。

示例定位:Global Fetcher

examples/global-fetcher/README.md 明确说明了该示例的核心思想:

Use theSWRConfigprovider 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 dev

package.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

项目地址:https://gitcode.com/gh_mirrors/sw/swr
点击查看免费下载
上一篇:LangChain Extract扩展开发:添加自定义文件格式支持
下一篇:Nextra构建难题终极指南:从常见报错到快速解决方案的完整教程

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

返回列表