As our projects become increasingly complex, users are demanding higher speed and better user experiences. Relying solely on traditional request libraries like Axios or Fetch to handle data requests often results in a lot of redundant boilerplate code, which has long been criticized. This is where enhanced request libraries come into play.
Some of you might be wondering, "What exactly is an enhanced request library?" An enhanced request library typically builds on top of traditional request libraries and integrates deeply with UI frameworks like React and Vue through hooks. It also provides additional performance optimization features, such as response caching, to help reduce boilerplate code and improve request performance.
Currently, some of the most popular enhanced request libraries include @tanstack/react-query
, swr
, and the rising star alova
. Each has its unique features. Here, we'll take a deep dive into comparing them to help you determine which one best suits your project's needs. That way, when a new project requirement arises, you'll know exactly which tool to choose.
Quick channel for comparison tools
Let's start right now and compare them from the following 8 perspectives.
Product positioning and features
hooks
Framework support
Server support
Request method
Cache strategy
API automation solution
Performance
Comparison of Positioning and Features
First, let's discuss their different positioning.
@tanstack/react-query primarily focuses on managing asynchronous state. Its strength lies in helping you handle data fetching, caching, and synchronization. When you need data, it fetches it for you; when the data becomes stale, it updates it.
swr also focuses on asynchronous state management, using lightweight hooks to simplify data fetching.
alova provides a comprehensive request solution, mainly to help developers raise API integration efficiency. It reduces the number of steps for developers to use API from 7 to just 1, helping developers reduce a lot of API maintenance time.
Different positioning means these libraries have different design considerations. react-query
and swr
focus mainly on the hooks they provide and cache management functions. In contrast, alova
optimizes API consumption efficiency by taking a more holistic approach to the request strategy. It not only offers hooks but also includes hook middleware, global seamless refresh interceptors, and other features referred to as request strategies. It also provides automatic API generation and search extension plugins. Because of this, I believe alova
addresses API-related challenges in multiple aspects.
Let's look at a comparative example in React.
react-query
import { useQuery } from '@tanstack/react-query';
const fetchUsers = async () => fetch('https://api.example.com/users')
.then(res => res.json());
function UserList() {
const { data: users, isLoading, error } = useQuery('users', fetchUsers);
if (isLoading) return <div>Loading...</div>;
if (error) return <div>An error occurred: {error.message}</div>;
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
export default UserList;
swr
import useSWR from 'swr';
const fetcher = url => fetch(url)
.then(res => res.json());
function UserList() {
const { data: users, error } = useSWR('https://api.example.com/users', fetcher);
if (!users) return <div>Loading...</div>;
if (error) return <div>An error occurred: {error.message}</div>;
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
export default UserList;
alova
import { createAlova, useRequest } from 'alova';
import adapterFetch from 'alova/fetch';
import ReactHook from 'alova/react';
const alovaInstance = createAlova({
baseURL: 'https://api.example.com',
statesHook: ReactHook,
requestAdapter: adapterFetch(),
});
function UserList() {
const methodInstance = alovaInstance.Get('/users');
const { loading, data: users, error } = useRequest(methodInstance);
if (loading) return <div>Loading...</div>;
if (error) return <div>An error occurred: {error.message}</div>;
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
export default UserList;
You can see. react-query
andswr
send requests directly with asynchronous functions, whilealova
needs to create a request instance in advance, which defines how to send requests using the fetch adapter under react. In addition, adapters such asxmlhttprequest
andaxios
are also provided. These are all due to their positioning-dominated design concepts, and these differences will be reflected in the following comparisons.
Comparison of hooks
Number of hooks
@tanstack/react-query provides hooks such as
useQuery
,useMutation
, anduseInfiniteQuery
.swr mainly provides hooks such as
useSWR
anduseSWRInfinite
.alova provides a total of 15+ request strategies in different request scenarios, including
useRequest
,useWatcher
,usePagination
,useFetcher
,useForm
, etc.
hook actions
One of the features of alova's hooks is that its scenario-based hooks also provide a wealth of actions, which allow developers to more finely control data operations and quickly implement the comprehensive functionality of different complex requests, which is not available in react-query
and swr
. For example, the following is actions for paging request.
import { usePagination, useForm } from "alova/client";
// Pagination request example
const {
loading,
data,
page,
pageSize,
pageCount,
total,
insert,
remove,
replace,
refresh,
reload,
} = usePagination((page, pageSize) => getUserList({ page, pageSize }), {
initialPage: 1,
initialPageSize: 10,
});
// Use actions
const handleAddUser = (newUser) => {
insert(newUser);
};
const handleRemoveUser = (userId) => {
remove((user) => user.id === userId);
};
hooks middleware support
alova and swr's hooks support middleware, allowing more fine-grained customization during the request process. But react-query
does not support it.
swr
function myMiddleware (useSWRNext) {
return (key, fetcher, config) => {
// Before hook runs...
// Process the next middleware, or the `useSWR` hook if this is the last one.
const swr = useSWRNext(key, fetcher, config)
// After the hook runs...
return swr
}
}
<SWRConfig value={{ use: [myMiddleware] }}>
// Or...
useSWR(key, fetcher, { use: [myMiddleware] })
alova
import { useRequest } from "alova/client";
// Define a middleware
const loggingMiddleware = async (context, next) => {
console.log("Request started:", context.config);
const response = await next();
console.log("Request ended:", response);
};
// Use middleware in hook
const { loading, data } = useRequest(getUserList, {
middleware: loggingMiddleware,
});
Framework support
Client
- @tanstack/react-query supports mainstream UI frameworks in the form of independent packages, although it was originally designed for React.
- react:
@tanstack/react-query
- vue:
@tanstack/vue-query
- svelte:
@tanstack/svelte-query
- angular:
@tanstack/angular-query
- solid:
@tanstack/solid-query
- swr only supports react.
-
alova supports frameworks such as
react/vue/svelte
with a single package + UI framework adapter, unifying the user experience under each UI framework.
SSR
All three support mainstream SSR frameworks.
Server support
@tanstack/react-query and swr mainly provide clienthooks for client applications. Although they can be used in a server-side rendering (SSR) environment, they cannot be used directly in a non-SSR server-side environment, but they do not provide APIs used in pure server-side environments (such as Express or Koa route handlers).
In contrast, alova not only fully supports server-side programs, but also provides server-side request strategies for the server-side environment. They are called server hooks, which makes it easier and more flexible to control requests on the server side.
The following is an example of sending a verification code with retry:
const { retry, sendCaptcha } = require("alova/server");
app.get("/api/captcha/send", async (req, res) => {
const email = req.params.email;
// Create a method instance for sending a verification code
const captchaMethod = alovaInstance.Post("/api/captcha", {
email,
content: "captcha content",
});
// Use retry hook to wrap captchaMethod
const retringMethod = retry(captchaMethod, {
retry: 3,
backoff: {
delay: 2000,
},
});
// Use sendCaptcha hook to wrap retringMethod, and send the request and get the response result through await
const result = await sendCaptcha(retringMethod, {
key: email,
});
});
Request method
@tanstack/react-query
and swr
provide asynchronous functions to receive request data. Users need to directly use axios
or fetch
third-party request libraries to obtain data and provide it to @tanstack/react-query
and swr
. This gives all control of the request to the user, and even simulates the request in the asynchronous function.
const fetchUsers = async () =>
new Promise((resolve) => {
setTimeout(() => {
resolve({ data: "your data" });
}, 1000);
});
const { data: users, isLoading, error } = useQuery("users", fetchUsers);
But alova
uses Method as a proxy object, which has the following advantages for me:
Provides a unified request method. Users do not need to care about what method is used for request except setting the request adapter.
It has various uses. Users can use Method to send requests directly like axios, and can also directly pass it into hooks to control requests.
// Direct request
const res = await alvoaInstance.Get("/users");
// Pass in request in useRequest
const { loading, data, error } = useRequest(alvoaInstance.Get("/users"));
For example, using
XMLHttpRequest
request can also get a complete and unified experience, including global interceptors. Alova providesXMLHttpRequest
adapter, but it needs to be encapsulated in@tanstack/react-query
andswr
.Easy to port to other projects, just change the request interceptor globally.
Cache strategy
@tanstack/react-query
Fine cache control:
@tanstack/react-query
allows to configurestaleTime
andcacheTime
to determine the cache duration and expiration time of data.Automatic refresh and invalidation: Configure automatic refresh of data under certain conditions through options such as
refetchOnWindowFocus
andrefetchOnReconnect
.Cache data persistence: Implement persistent storage of client cache data through the
persistQueryClient
plugin.Cache debugging tool: Provides
ReactQueryDevtools
debugging tool for observing and processing data requests and cache status.
swr
-
Custom global cache: SWR uses a global cache to share data, and allows customizing how to store cache through the
provider
option ofSWRConfig
. -
Modify cache data: Provides
mutate
function to modify the cache, including clearing all cached data or updating specific cache items. - Cache debugging tool: View and debug through browser extensions.
alova
- Multi-level cache: Supports L1 and L2 multi-level cache, and can restore data from persistent storage after the memory cache is invalidated to adapt to different usage scenarios.
- Fine cache control: Allows you to set different expiration times for different levels of cache, providing more flexible cache management.
- Automatic cache invalidation: Automatically invalidate the corresponding cache by specifying the relationship between APIs, reducing the trouble of manual invalidation.
-
Flexible cache storage: You can use any cache storage to store data, such as
localStorage
,sessionStorage
,indexedDB
on the client,AsyncStorage
under react-native, and@alova/psc
shared by multiple processes on the server, or even redis storage shared by clusters.
API Automation Solution
Since @tanstack/react-query
and swr
give all control of the request to the user, the API automation solution is provided by third-party request tools. For example, axios
and fetch
can automatically generate request codes through openapi-generator or @openapitools/openapi-generator-cli.
Alova provides a more advanced openAPI solution. , including the following:
Generate API call code, TypeScript type and detailed API documentation for each API at the same time, so that you can enjoy complete API type hints even in JavaScript projects, which are not available in
openapi-generator
and@openapitools/openapi-generator-cli
.A brand new API integration experience. In the past, when the backend developer delivered the API to you, you needed to open the intermediate API document to query and copy key information to your project. You needed to constantly switch between the API document and the editor in the middle, but now, Alova's development tools can eliminate the intermediate API document for you, shortening the collaboration distance between the front and back ends like a wormhole. Through it, you can quickly find the required API in the editor and display the complete documentation of this API, and quickly complete parameter transfer by referring to the API parameter table.
- Update the API regularly and actively notify the front-end development, no longer relying on the notification of the server-side developer.
Performance
Dependency collection
Dependency collection refers to the automatic tracking of the status of component dependencies within hooks. When the status of the dependency changes, it will trigger the re-rendering of the view. This is more of a way to reduce the rendering of react components.
swr
and alova
both support dependency collection, while @tanstack/react-query
does not.
Alova's unique performance features
Request sharing
Request sharing means that when multiple identical requests are issued at the same time, only one request will be actually issued, and the response data will be shared with these requests. It can not only improve the fluency of the application, but also reduce the pressure on the server.
@tanstack/react-query
and swr
are not supported, alova
is supported on both the client and the server.
hooks performance optimization
Compared with @tanstack/react-query
and swr
hooks, one feature of alova's scenario-based hooks is that it can optimize performance for specific scenarios, for example:
usePagination
can automatically pre-fetch the list data of the previous and next pages, so that users do not need to wait when turning pages (turning pages in seconds)useForm
provides a form draft, and unsubmitted data will not be deleted even if it is refreshed
Default GET cache
Since alova's cache key is automatically calculated through the request information of the method instance, by default, alova's GET has a 5-minute cache, and there is no need to repeat the request when multiple requests for duplicate data are made.
Conclusion
After an in-depth discussion, we have a more comprehensive understanding of the three request enhancement libraries alova
, @tanstack/react-query
and swr
. Each library has its own unique advantages and applicable scenarios. Which library to choose ultimately depends on your project requirements, the team's technology stack, and considerations of performance, ease of use, and flexibility.
swr is known for its simplicity and ease of use. If you are looking for a lightweight and easy-to-use solution, or your project focuses on fast rendering and minimizing server requests, srw will be an ideal choice.
For applications that require powerful state management and caching capabilities,
@tanstack/react-query
is a good choice.If you don't want to spend more time on API use, want to find a unified request solution, or are sending requests in Express or koa, alova may be more suitable for your needs.
There is no best library, only the one that best suits your project. Take the time to evaluate and compare different tools, and finally choose the one that can help you and your team work more efficiently and happily.
I hope this article can help you better understand the characteristics of these three request enhancement libraries and make wise choices in actual projects.
Bye everyone!!!
Top comments (0)