现代前端框架实战(5):数据请求与缓存
上一篇把本地、URL、全局与服务端状态分开本篇专攻最后一类。任务列表会用稳定缓存键表达依赖用 staleTime 表达“多久仍可信”并在修改时乐观更新、失败回滚、成功后再验证。一、痛点fetch 只解决传输在 Effect 中fetch还要自行处理加载、错误、组件卸载、重复请求、竞态、重试、窗口聚焦刷新和跨组件共享。更隐蔽的是旧请求后返回覆盖新筛选结果。TanStack Query 把一次查询建模为queryKey queryFn键是缓存身份函数负责获取。凡是影响结果的项目 ID、筛选、页码都必须进入键。缓存不是越久越好。staleTime表示数据在多长时间内仍新鲜gcTime表示无人订阅后保留多久前者决定是否应后台刷新后者决定内存回收。任务列表可允许几十秒陈旧权限判断与库存则需要更短窗口。HTTP Cache-Control 与客户端缓存可并存但必须明确每层失效责任。开始实现前应为每类数据写“可陈旧预算”。项目名称也许五分钟内不变协作任务允许三十秒支付状态则必须立即确认。预算来自业务后果而非库默认值数据晚一分钟会导致用户做错什么是否能通过明显的刷新提示弥补。这样即使未来换成 SWR、Apollo 或自研缓存团队仍知道该如何配置新鲜度。二、原理缓存键是数据函数的参数同一键必须对应同一语义。把对象字段排序或使用库提供的确定性哈希避免逻辑相同却生成多份缓存。请求函数收到取消信号时应传给 fetch用户快速切筛选旧请求即可终止减少带宽和错误覆盖。键还承担失效范围的索引。可以用层级工厂生成tasks.all、tasks.lists()、tasks.list(projectId, filters)和tasks.detail(id)调用方不手写结构。影响结果的租户、项目、筛选、排序、分页和语言都应进入键纯展示状态不应进入。若请求函数偷偷读取键外的变量同一个键就可能返回不同结果缓存将失去正确性。importjsonfromdataclassesimportdataclassdataclassclassEntry:value:objectsaved_at:intstale_after:intdefquery_key(project_id,filters):stablejson.dumps(filters,sort_keysTrue,ensure_asciiFalse)returnftasks:{project_id}:{stable}defread(cache,key,now):entrycache.get(key)ifentryisNone:returnmiss,Noneagenow-entry.saved_at statusfreshifageentry.stale_afterelsestalereturnstatus,entry.value keyquery_key(42,{status:open,owner:me})cache{key:Entry([编写缓存],saved_at100,stale_after30)}fornowin(110,140):status,valueread(cache,key,now)print(now,status,value)运行输出110 fresh [编写缓存] 140 stale [编写缓存]三、实现查询、变更与乐观更新创建单一 QueryClient在客户端 Provider 注入。查询键工厂集中生成[tasks, projectId, filters]避免字符串散落。UI 分清首次 pending 与已有数据时 fetching首次显示骨架后台刷新只显示轻量指示不要把稳定列表清空。错误展示可重试操作并区分认证、校验和暂时网络错误。乐观更新适用于成功概率高、回滚清晰的操作。onMutate先取消相关查询保存旧值再写入预测结果onError恢复快照onSettled失效查询让服务器成为最终裁判。创建任务还需临时 ID 与服务器 ID 对账。涉及付款或不可逆操作不要用“看起来成功”的乐观界面。fromcopyimportdeepcopy cache{tasks:42:[{id:1,title:搭建环境,done:True},{id:2,title:实现缓存,done:False},]}defoptimistic_toggle(store,key,task_id,server_accepts):snapshotdeepcopy(store[key])store[key][{**task,done:nottask[done]}iftask[id]task_idelsetaskfortaskinstore[key]]ifnotserver_accepts:store[key]snapshotreturnrolled backreturnconfirmedprint(optimistic_toggle(cache,tasks:42,2,True))print(cache[tasks:42][1])print(optimistic_toggle(cache,tasks:42,1,False))print(cache[tasks:42][0])运行输出confirmed {id: 2, title: 实现缓存, done: True} rolled back {id: 1, title: 搭建环境, done: True}服务端预取后可脱水给客户端避免首屏再次等待但要确保 QueryClient 按请求创建且只序列化可公开数据。API 层统一检查response.ok、解析错误结构并返回领域类型组件不应重复拼 URL 和翻译状态码。乐观创建比切换状态更复杂因为客户端尚无真实 ID。临时对象应带明确临时标记成功后用服务端实体替换失败后移除并保留表单输入。若用户在确认前又编辑临时任务要定义合并顺序无法清楚回滚时宁可显示提交中并等待确认。乐观更新不是速度开关而是一笔必须可逆、可对账的本地事务。错误也需要分类。认证失败交给会话层字段错误回到表单短暂网络故障允许重试资源冲突则刷新最新版本并提示用户。盲目对所有错误指数重试会放大服务端压力也可能重复非幂等写入。读取请求可在网络错误和部分服务器错误上有限重试写入请求则依赖服务端幂等键与明确策略。四、踩坑失效不是清空全部缓存每次修改后清空所有查询会制造请求风暴。根据实体关系精确失效切换任务影响该项目列表与任务详情未必影响其他项目。反之漏掉筛选维度会让不同视图共享错误数据。无限滚动的页参数也必须进入结构。另一个误区是把后台刷新显示成整页加载。缓存已有可用数据时应保留内容并显示轻量刷新状态只有首次没有数据才使用骨架。否则窗口重新聚焦就会让页面闪空用户也无法判断是刷新还是数据丢失。与此同时旧数据若具有风险需要明确标注更新时间或暂时禁止关键操作不能为了平滑而隐藏陈旧性。默认重试对 GET 通常合理对非幂等 POST 可能重复创建。接口应支持幂等键客户端按错误类型决定重试。预取也不是越多越好只预取高概率下一步并观察命中率与流量。五、验证用时间与乱序测试测试新鲜期内不重复取数、过期后保留旧数据并后台刷新、快速切筛选时旧响应不覆盖、失败乐观更新恢复原值、离线后重连刷新。开发工具观察键、观察者与失效过程网络面板检查重复请求。指标同时记录命中率、错误率、数据可见延迟和后台流量。测试时使用可控时钟和可控 Promise而不是依赖真实等待。先发起open再发起done故意让前者后返回确认当前视图仍是done让变更在乐观写入后失败确认列表、详情和统计一起恢复卸载所有消费者并推进时间确认到达回收期后条目消失。最后查看服务端日志验证一次用户动作产生的请求数量符合预期。这套方法的可迁移核心是四件事完整身份键、业务新鲜度、可逆变更和精确失效。库只替你实现调度不替你定义语义。下一篇的设计系统可以放心消费稳定数据状态而无需在按钮和列表中各自处理请求竞态。下一篇将在稳定数据层之上建立样式与组件库用设计令牌统一颜色和间距用可访问的基础组件承载交互并处理 CSS 隔离、主题和服务端渲染取舍。参考来源TanStack QueryReact 文档MDNAbortControllerMDNHTTP Caching 觉得有用就点个赞 收藏方便回头查阅有疑问直接在评论区留言我看到都会回。 本文属于《现代前端框架实战》系列持续更新关注不迷路。 文章里的代码都能直接跑。想要可直接 clone 的完整工程 配套部署脚本 / 踩坑清单评论一声或发邮件到cj2664qq.com我免费发你。如果你正好在做类似系统、或有工程化难题想找人做也欢迎邮件聊一句——我按实际情况评估能落地的就接单或出方案。评论和邮件都能直接找到我不用跳别的平台。

相关新闻

微信小程序电影订票系统全栈实战:从云开发选型到高并发选座实现

微信小程序电影订票系统全栈实战:从云开发选型到高并发选座实现

1. 项目缘起:为什么选择微信小程序做电影订票? 最近几年,如果你留意过电影院门口排队的人群,或者打开过手机上的购票App,你会发现一个明显的趋势:线上订票已经成为绝对主流。作为一个在互联网产品领域摸爬滚…

2026/8/27 8:11:09 阅读更多 →
超紧凑50W DC-DC实战:48V转12V同步Buck设计全流程

超紧凑50W DC-DC实战:48V转12V同步Buck设计全流程

开头直接切人话题,不铺垫。我在去年接了个边缘计算网关的项目,结构那边只给电源板留了 2525 毫米的面积,要求输出 12V/4.2A,也就是 50W 的 DC-DC 转换器,输入是标准的 48V POE 电压。说白了就是要在半个火柴盒大小的空…

2026/8/27 8:11:09 阅读更多 →
Cloudflare Bot管理实战:识别自动化流量与AI Agent应对

Cloudflare Bot管理实战:识别自动化流量与AI Agent应对

如果你的业务用了 Cloudflare,或者你写过脚本访问过某个套了 Cloudflare 的站点,大概率见过这台“拦路虎”:Were sorry... but your computer or network may be sending automated queries.初次遇到这个提示,很容易以为只是普通的…

2026/8/27 8:11:09 阅读更多 →

最新新闻

AI编程成本控制:手写递归下降解析器实现mini C++解释器

AI编程成本控制:手写递归下降解析器实现mini C++解释器

看到“I Spent 2B Tokens Writing a C Compiler So You Dont Have To”这样的标题时,很多人的第一反应是:这得烧多少钱?答案可能已经不重要,但这件事背后藏着一个更值得关注的技术信号——AI 已经能够在 C 编译器这种最高难度的系…

2026/8/27 8:57:50 阅读更多 →
线段树维护区间最大子段和:从算法竞赛真题到高效数据结构应用

线段树维护区间最大子段和:从算法竞赛真题到高效数据结构应用

1. 从一道“区间最大和”真题,聊聊算法竞赛中的经典套路与实战避坑最近在整理蓝桥杯的历年真题,特别是算法训练(ALGO)部分的题目,发现很多同学在遇到“区间最大和”这类问题时,常常会陷入一个误区&#xff…

2026/8/27 8:57:49 阅读更多 →
内存安全是无用的概念?拆解三层含义与工程真相

内存安全是无用的概念?拆解三层含义与工程真相

内存安全是“无用的概念”?别急着反驳,先想清楚这三层意思如果你关注过近几年编程语言圈的讨论,大概率见过这样的句式:某个语言“内存安全”,所以它比 C/C 更适合做系统编程;又或者,某个语言因为…

2026/8/27 8:57:49 阅读更多 →
CentOS 7.9 服务器 Docker 安装与配置全流程详解

CentOS 7.9 服务器 Docker 安装与配置全流程详解

1. 项目概述:从虚拟化到容器化的关键一步如果你在服务器运维、应用开发或者仅仅是技术爱好者圈子里待过一阵子,那么“Docker”这个词对你来说肯定不陌生。它几乎成了现代软件部署和微服务架构的代名词。但很多时候,当我们兴致勃勃地打开教程&…

2026/8/27 8:57:49 阅读更多 →
Python数学建模全流程实战:从数据处理到模型部署

Python数学建模全流程实战:从数据处理到模型部署

1. 项目概述:为什么是Python数学建模?如果你正在读这篇文章,大概率是刚接触数学建模,或者已经用Matlab、Lingo等传统工具建模多年,正考虑转向Python。我最初也是从Matlab转过来的,当时最大的感受是&#xf…

2026/8/27 8:57:49 阅读更多 →
9月9日苹果发布会:折叠屏iPhone等新品将登场,新CEO特努斯首秀!

9月9日苹果发布会:折叠屏iPhone等新品将登场,新CEO特努斯首秀!

苹果“惊喜与闪耀”发布会何时举行? 今年,苹果年度产品发布会将于太平洋时间9月9日上午10点(东部时间下午1点)举行,地点在库比蒂诺。ZDNET将在现场,于史蒂夫乔布斯剧院观看苹果发布全新系列产品。线上观众可…

2026/8/27 8:56:49 阅读更多 →

日新闻

Go语言构建企业级AI服务网关:统一管理英伟达等AI接口调用

Go语言构建企业级AI服务网关:统一管理英伟达等AI接口调用

1. 项目概述:从零构建一个企业级的AI服务网关 最近在帮一个做内容审核的团队做技术架构升级,他们原来的业务里,每天有几十万张图片和短视频需要过审,最初是接了几个开源的AI模型自己部署,但效果和性能一直不太稳定。后…

2026/8/27 0:00:51 阅读更多 →
网盘直链下载助手5分钟解析八大网盘真实地址

网盘直链下载助手5分钟解析八大网盘真实地址

网盘直链下载助手5分钟解析八大网盘真实地址 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 / 迅雷云盘 / 夸…

2026/8/27 1:06:27 阅读更多 →
从零点亮 ESP32:Arduino ESP32 开发环境搭建与首次烧录完整指南

从零点亮 ESP32:Arduino ESP32 开发环境搭建与首次烧录完整指南

从零点亮 ESP32:Arduino ESP32 开发环境搭建与首次烧录完整指南 【免费下载链接】arduino-esp32 Arduino core for the ESP32 family of SoCs 项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32 Arduino ESP32 是乐鑫官方的 ESP32 系列 Ardui…

2026/8/27 1:06:27 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/26 14:45:33 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/26 17:46:43 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/26 14:46:37 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/26 3:50:20 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/26 17:46:39 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/26 1:24:05 阅读更多 →