在 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. 基本使用

javascript 复制代码
import ky from 'ky';

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

这行代码已经等价于:

javascript 复制代码
const res = await fetch('/api/users');
const data = await res.json();

但 Ky 提供了:

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

  • 直接解析 JSON

  • 更简洁的 API 语法


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

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

javascript 复制代码
// 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;

使用示例:

javascript 复制代码
// 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. 安装

bash 复制代码
npm install @tanstack/react-query

2. 配置 QueryClient

javascript 复制代码
// 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 实战

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

javascript 复制代码
// 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>
      <button
        onClick={() => mutation.mutate({ name: '新名字' })}
        className="mt-2 px-3 py-1 bg-blue-500 text-white rounded"
      >
        修改姓名
      </button>
    </div>
  );
}

这样,我们就实现了:

  • 自动缓存用户信息

  • 更新后自动刷新

  • 异步状态统一管理

  • Ky 提供更优雅的请求层


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

1. 全局错误处理

可在 QueryClient 中定义默认行为:

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

2. 全局 Loading 监控

javascript 复制代码
import { useIsFetching } from '@tanstack/react-query';

function GlobalLoading() {
  const isFetching = useIsFetching();
  return isFetching ? <div className="loading-bar" /> : null;
}

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


七、Ky vs Axios 对比总结

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

如果你的项目是纯前端 SPA,Ky 是更优雅、现代的选择。

若要兼容 SSR 或 Node 环境,Axios 仍有优势。


八、总结

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

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


延伸阅读

相关推荐
小程故事多_802 小时前
LangGraph系列:多智能体终极方案,ReAct+MCP工业级供应链系统
人工智能·react.js·langchain
夏日不想说话2 小时前
一文搞懂 AI 流式响应
前端·node.js·openai
顾安r2 小时前
11.14 脚本网页 青蛙过河
服务器·前端·python·游戏·html
不爱吃糖的程序媛3 小时前
Electron 智能文件分析器开发实战适配鸿蒙
前端·javascript·electron
Doro再努力3 小时前
2025_11_14洛谷【入门1】数据结构刷题小结
前端·数据结构·算法
IT_陈寒3 小时前
SpringBoot 3.2新特性实战:这5个隐藏技巧让你的应用性能飙升50%
前端·人工智能·后端
Java追光着3 小时前
React Native 自建 JS Bundle OTA 更新系统:从零到一的完整实现与踩坑记录
javascript·react native·react.js
努力往上爬de蜗牛3 小时前
react native 运行问题和调试 --持续更新
javascript·react native·react.js
eason_fan4 小时前
Monorepo性能噩梦:一行配置解决VSCode卡顿与TS类型崩溃
前端·typescript·visual studio code