跳到主要内容

2 篇博文 含有标签「对比」

查看所有标签

react-query 还是 alova:看请求跑不跑出浏览器

· 阅读需 4 分钟
Alova Team

选数据请求库,通常开头都是「谁的缓存更好」。这个问题跳过了一个事后才咬人的点:你的请求到底跑在哪?

如果你的请求全在浏览器里、而且用 React,react-query 是成熟、踩坑少的选择。可一旦你需要同一套请求逻辑跑在「不是 React Native 的手机端」,或者跑在一个调下游服务的 BFF 里,地图就变了。alova 把这些情况收到了同一套 API 下。这篇是直来直去的对比,也包括 alova 更弱的地方。

react-query 明显领先的地方

先讲诚实的一面:

  • 和 React 贴合。 react-query 是围着 React 的渲染模型建的。useQuery 这类 hook 天然嵌进组件,它的 devtools 和查询面板是这个领域里最顺手的。
  • 缓存成熟度。 它的缓存、去重、后台重拉、stale-while-revalidate,在大量生产应用里被反复验证过。
  • 社区与答案。 这么多年的 Stack Overflow、博客、能直接抄的片段,意味着大部分问题网上已经有人解过了。

如果你的前端是 React、只在浏览器里、你也对这个生态满意,react-query 是更稳的默认。说反话是不诚实的。

alova 走得更远的地方

alova 也是请求策略层,但它不绑死某个框架或某个运行时:

  • 一套 API 跨运行时。 同一套 useRequestusePagination 调用,跑在 Web、移动端(React Native / Expo / uni-app / Taro / 小程序)、以及服务端(Node BFF)。请求逻辑你只写一遍。
  • 服务端 hook。 alova/server 给 BFF 的出站调用加了 retrycreateRateLimiter,这一层 react-query 管不到,因为它活在浏览器里。
  • 框架任选。 React、Vue、Svelte、Solid 都有一等公民级别的 hook,混合技术栈的团队不必被绑进 React。
  • 站在你现有的适配器上。 alova 自己不发请求,它跑在 fetch 或 axios 适配器之上,所以你已经在用 axios 的话,它继续干活。

逐项对照

关注点react-queryalova
主运行时浏览器(React)Web、移动端、服务端(BFF)
框架React 优先React / Vue / Svelte / Solid
客户端缓存极佳、成熟不错,策略 hook
服务端重试 / 限流不归它管alova/server hook
跨端 App仅 React NativeReact Native、Expo、uni-app、Taro、小程序
自己发 HTTP否(底层 fetch/axios)否(fetch/axios 适配器)
社区规模非常大较小

最后一行说明:两个库都不替代 axios。它们都坐在请求适配器之上,所以团队已经在用 axios 的话,发请求还是它的活。

什么时候 react-query 更对

  • 前端是 React、只在浏览器,你想要最深的 React 缓存生态。
  • 你不跑一个需要出站重试/限流的 BFF。
  • 团队已经熟 react-query,用它出活快。

什么时候 alova 更合适

  • 你要跨 Web、非 React Native 的 App、Node BFF 维护同一套请求逻辑。
  • 你的 BFF 需要对下游调用做退避重试加客户端限流(见 BFF 重试那篇)。
  • 你在用 Vue/Svelte/Solid,或混合栈,想要一个策略层。

什么情况下两个都不需要

如果你就发几个请求,手写 loading/data/error 三个状态也不重复,那 fetch 加一个小封装就够了。两个库只有在「同一类请求模式反复出现」时才值回票价。

axios 和 alova 一起用,谁管什么

· 阅读需 3 分钟
Alova Team

一句话:它们是分层关系,不是二选一。 axios 是 HTTP 客户端,负责把请求发出去;alova 是请求策略层,负责「怎么请求」——分页、缓存、重试、去重、token 刷新。alova 可以把 axios 用作请求适配器(@alova/adapter-axios),所以选 alova 从来不意味着扔掉 axios。

alova 的定位:一套请求 API,跑在 Web、App(uni-app/Taro/小程序)、服务端(BFF)。

分工表

关注点axiosalova
发送 HTTP 请求✅ 本职交给适配器(fetch / XHR / axios / uni-app / Taro)
拦截器beforeRequest / responded(你的 axios 拦截器继续生效)
loading / error / data 状态手写useRequest 等自动管理
分页、表单、上传、SSE 流程手写✅ 20+ 现成策略 hooks
响应缓存手写✅ 多级缓存(L1/L2)+声明式失效
相同并发请求去重手写✅ 内置请求共享
跨端(uni-app / Taro / 小程序)社区封装✅ 官方适配器,同一套 API
服务端重试 / 限流手写alova/server

axios 实打实更强的地方

诚实的对比要写两面:

  • 生态与熟悉度。 axios 拥有 JavaScript 世界最大的社区之一,几乎每个边角问题都有现成答案,几乎每个开发者都用过它;alova 的社区规模远小于它。
  • 团队零学习成本。 所有人都会 axios.get();alova 引入了 Method 抽象和策略 hooks,这是真实存在的(虽然不大的)心智负担。
  • 请求本来就少的项目,axios 单独用就够了。策略层只有在你反复手写同样的请求逻辑时才值回票价。

两个一起用长什么样

保留你现有的 axios 实例——包括拦截器和 baseURL——让 alova 来驱动它:

import axios from 'axios';
import { createAlova } from 'alova';
import { axiosRequestAdapter } from '@alova/adapter-axios';
import VueHook from 'alova/vue';

// 你现有的 axios 实例,一行不改
const customAxios = axios.create({ baseURL: '/api', timeout: 10000 });

const alovaInst = createAlova({
statesHook: VueHook,
requestAdapter: axiosRequestAdapter({ axios: customAxios })
});

Vue 3 里一个普通请求的前后对比:

// 只用 axios:手写三个状态
const loading = ref(false);
const data = ref({});
const error = ref(null);
const load = async () => {
try {
loading.value = true;
data.value = await customAxios.get('/todos');
} catch (e) {
error.value = e;
}
loading.value = false;
};
onMounted(load);

// axios + alova:状态自动管理
const { loading, data, error } = useRequest(alovaInst.Get('/todos'));

你为 axios 做的配置全部继续有效:method 配置支持 axios 的全部请求选项;拦截器顺序也是确定的——alova 的 beforeRequest 先于 axios 请求拦截器触发,alova 的 responded 晚于 axios 响应拦截器触发。

什么情况下你不需要 alova

  • 项目请求本来就少,没有反复出现的分页/缓存/重试样板——直接用 axios 就是正确选择。
  • 纯 React、纯 Web、且已深度使用 React Query——除非你需要跨端或服务端策略,否则切换收益不大。
  • 你想要零抽象的技术栈——alova 的 Method + hooks 模型是多一层概念,这个成本是真实的。

下一步