当前位置: 首页 > news >正文

在 React 项目中使用 Ky 与 TanStack Query 构建现代化数据请求层

适用版本: React 19 + Vite + TypeScript
核心技术: Ky + TanStack Query
适用场景: 替代 Axios + 手写 useEffect 请求逻辑的现代方案


一、背景:从 Axios 到现代 Fetch 封装

过去我们常使用 Axios 处理请求,它提供了:

  • 拦截器(interceptor)

  • 超时控制

  • 响应转换

  • 请求取消

但现代浏览器的 Fetch API 已经非常强大,
如果能在其基础上进行更轻量的封装,将获得更好的兼容性与性能。

Ky 就是这样一款工具,它是对 fetch 的现代化封装,简洁、可扩展、TypeScript 友好。
再搭配 TanStack Query(即 react-query),就能轻松实现:

  • 自动缓存与刷新

  • 错误重试

  • 加载状态管理

  • 数据同步与失效机制

这两者组合,堪称“前端数据层的黄金搭档”。


二、Ky 简介:轻量级的 Fetch 封装

1. 安装

npm install ky

yarn add ky

2. 基本使用

import ky from 'ky';const data = await ky.get('/api/users').json();

这行代码已经等价于:

const res = await fetch('/api/users');
const data = await res.json();

但 Ky 提供了:

  • 自动抛出错误(非 2xx 响应)

  • 直接解析 JSON

  • 更简洁的 API 语法


三、创建 Ky 实例(封装请求层)

为了支持 Token、Base URL、统一错误处理等,我们可以创建一个自定义实例:

// src/api/kyInstance.ts
import ky from 'ky';const api = ky.create({prefixUrl: import.meta.env.VITE_API_BASE_URL,timeout: 10000,credentials: 'include',hooks: {beforeRequest: [request => {const token = localStorage.getItem('token');if (token) {request.headers.set('Authorization', `Bearer ${token}`);}},],afterResponse: [async (_request, _options, response) => {if (response.status === 401) {// 自动登出或跳转登录页window.location.href = '/login';}},],},
});export default api;

使用示例:

// src/api/user.ts
import api from './kyInstance';export const getUser = () => api.get('user/profile').json<User>();
export const updateUser = (data: Partial<User>) =>api.patch('user/profile', { json: data }).json<User>();

Ky 设计哲学就是——fetch but better
保持简洁,不额外造轮子。


四、TanStack Query:智能的数据层管理

Ky 负责 请求,而 TanStack Query 负责 状态与缓存
我们再也不用在组件里管理 loading、error、refresh 逻辑了。

1. 安装

npm install @tanstack/react-query

2. 配置 QueryClient

// src/main.tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import ReactDOM from 'react-dom/client';
import App from './App';const queryClient = new QueryClient();ReactDOM.createRoot(document.getElementById('root')!).render(<QueryClientProvider client={queryClient}><App /></QueryClientProvider>
);

五、结合使用:Ky + TanStack Query 实战

假设我们要在页面中显示用户信息:

// src/pages/Profile.tsx
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { getUser, updateUser } from '@/api/user';export default function Profile() {const queryClient = useQueryClient();const { data, isLoading, isError } = useQuery({queryKey: ['user'],queryFn: getUser,});const mutation = useMutation({mutationFn: updateUser,onSuccess: () => {// 更新缓存queryClient.invalidateQueries({ queryKey: ['user'] });},});if (isLoading) return <p>加载中...</p>;if (isError) return <p>加载失败</p>;return (<div className="p-4"><h1>👤 用户资料</h1><p>姓名:{data.name}</p><buttononClick={() => mutation.mutate({ name: '新名字' })}className="mt-2 px-3 py-1 bg-blue-500 text-white rounded">修改姓名</button></div>);
}

这样,我们就实现了:

  • 自动缓存用户信息

  • 更新后自动刷新

  • 异步状态统一管理

  • Ky 提供更优雅的请求层


六、进阶技巧:错误处理 + 请求重试 + 全局 Loading

1. 全局错误处理

可在 QueryClient 中定义默认行为:

const queryClient = new QueryClient({defaultOptions: {queries: {retry: 2,refetchOnWindowFocus: false,onError: error => {console.error('Query Error:', error);},},},
});

2. 全局 Loading 监控

import { useIsFetching } from '@tanstack/react-query';function GlobalLoading() {const isFetching = useIsFetching();return isFetching ? <div className="loading-bar" /> : null;
}

可在根组件中挂载,实现任意请求时的 Loading 条。


七、Ky vs Axios 对比总结

特性KyAxios
基于FetchXHR
体积小(~7KB)大(~20KB)
支持拦截器✅ Hooks机制✅ 拦截器
TypeScript 支持✅ 原生✅ 完善
超时控制✅ 内置✅ 内置
JSON 解析✅ 一行搞定❌ 手动解析
语法风格函数式、现代面向对象式
Node.js 支持❌(需 polyfill)

如果你的项目是纯前端 SPA,Ky 是更优雅、现代的选择。
若要兼容 SSR 或 Node 环境,Axios 仍有优势。


八、总结

通过 Ky + TanStack Query 的组合,我们获得了:

更轻量的请求层:基于 Fetch,无需冗余 polyfill
智能的状态管理:数据缓存、失效、自动刷新
清晰的分层结构:API 层(Ky) + 数据层(Query)
可扩展性强:全局错误处理、重试策略、登录失效处理


延伸阅读

  • Ky 官方文档

  • TanStack Query 官方文档

  • React 19 文档

  • Vite 官方网站

http://www.dtcms.com/a/600666.html

相关文章:

  • 计算机网络---传输层安全 SSL与TLS
  • 【Linux篇】信号机制深度剖析:从信号捕捉到SIGCHLD信号处理
  • C语言编译软件选择及优化建议
  • Linux 之 【冯诺依曼体系结构与操作系统的简介】
  • 潍坊建设gc局网站windows优化软件
  • Java虚拟机(JVM)面试题(51道含答案)
  • [27] cuda 应用之 核函数实现图像通道变换
  • Aurora RDS MySQL The table ‘/rdsdbdata/tmp/#sql14b_df16d_1bd‘ is full
  • 手机响应式网站怎么做how to use wordpress
  • 网易云音乐回应“不适配鸿蒙”:推动相关部门加快步伐
  • C语言在线编译练习 | 提高编程技能与实战能力
  • 人工智能分支——深度学习、机器学习与神经网络初概览
  • C++ STL 关联式容器:map 与 set 深度解析与应用实践
  • 鄂尔多斯网站制作 建设推广网站建设前台功能
  • 策划书模板免费下载的网站免费获客平台
  • 如何搭建IoT机器视觉
  • 几分钟学会飞书多维表格开发
  • 11.12 脚本APP 手机如何开发简单APP
  • C++17常用新特性
  • oj题 ——— 链式二叉树oj题
  • 数据库项目实战五
  • Python调用Java接口失败(Java日志打印警告:JSON parse error:xxxx)
  • 没有网站如何做SEO推广有用吗怎么不花钱自己开网店
  • ArkTS分布式设计模式浅析
  • 倍福PGV100-F200A-R4-V19使用手册
  • FD2000/4的UEFI编译和烧录文件打包过程记录
  • 微信小程序map自定义气泡customCallout
  • 如何在ubuntu调用exe文件
  • Polar MISC (中)
  • 《理解数据在内存中的存储 --- 解密数据在计算机底层的存储秘密》