Frontend request code often involves repetitive state management. This article compares Axios and alova through a paginated list example, analyzing how request strategization reduces boilerplate and when it's a good fit.
The Pattern: Paginated List in Two Ways
A common requirement: fetch a user list with pagination.
Approach 1: Axios
const [data, setData] = useState([]);
const [page, setPage] = useState(1);
const [total, setTotal] = useState(0);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);
const fetchUsers = async (currentPage) => {
setLoading(true);
setError(null);
try {
const res = await axios.get('/api/users', {
params: { page: currentPage, pageSize: 10 },
});
setData(res.data.list);
setTotal(res.data.total);
} catch (e) {
setError(e.message);
} finally {
setLoading(false);
}
};
useEffect(() => { fetchUsers(page); }, [page]);
This pattern appears in nearly every data-fetching component. The actual business logic — GET /api/users — occupies a single line. The rest is infrastructure: state declarations, loading toggles, error handling, and effect management.
Approach 2: alova with usePagination
const {
data, total, loading, error,
page, pageSize, nextPage, prevPage,
} = usePagination(
(page, pageSize) => alovaInstance.Get('/api/users', {
params: { page, pageSize },
}),
{ page: 1, pageSize: 10 }
);
Both implementations are functionally identical. The key difference is where the state management logic lives: in the component (Axios) vs. inside the hook (alova).
What Changed
| Component of Axios version | Handled by alova |
|---|---|
loading state + toggling |
Managed internally by usePagination |
error state + try/catch |
Managed internally by usePagination |
data state + assignment |
Returned as reactive value |
page state + change handler |
Built-in nextPage / prevPage
|
total state extraction |
Extracted from response automatically |
| useEffect dependency tracking | Managed internally |
The removed code shares one characteristic: it's infrastructure for the request pattern, not business logic. alova encapsulates this infrastructure into scenario-specific hooks.
Beyond Pagination
alova provides hooks for common request patterns:
useRequest — basic fetch
// Auto-fetch on mount
const { data, loading, error } = useRequest(getUserList());
// Manual trigger
const { send } = useRequest(createOrder, { immediate: false });
useWatcher — reactive fetch with debounce
const { data } = useWatcher(
() => searchApi(keyword.value),
[keyword],
{ debounce: 300 }
);
useForm — form submission
const { form, loading, send: submit, reset } = useForm(
submitApi,
{ initialForm: { name: '', email: '' } }
);
All hooks share a consistent return interface (data, loading, error) while adding scenario-specific capabilities.
Code reduction across six common scenarios:
| Scenario | Axios (core lines) | alova (core lines) | Reduction |
|---|---|---|---|
| Paginated list | ~30 | 6 | ~80% |
| Search with debounce | ~25 | 3 | ~88% |
| Form submission | ~30 | 3 | ~90% |
| Polling / auto-refresh | ~25 | 3 | ~88% |
| Chained requests | ~30 | 5 | ~83% |
| File upload | ~35 | 8 | ~77% |
Line counts reflect core logic only, excluding UI rendering and imports.
When to Use (And When Not To)
Good fit for:
- Medium-to-large projects with many data-fetching pages
- Teams wanting consistent request patterns across codebase
- New projects where the abstraction can be established early
Less suitable for:
- Small projects where the abstraction overhead outweighs the benefit
- Teams already deeply invested in React Query or SWR — evaluate migration cost carefully
- Non-standard request patterns that don't map well to existing hooks
- Framework ecosystems outside of React/Vue/Svelte support
Other considerations:
- Learning curve: Understanding the strategy hook paradigm takes initial investment
- Debugging: The abstraction layer can add indirection when troubleshooting unexpected behavior
- Ecosystem: alova's community and third-party integrations are smaller than Axios'
- Migration path: The Method API mirrors Axios, enabling incremental adoption
// Nearly identical API
axios.get('/api/users', { params: { page: 1 } });
alovaInstance.Get('/api/users', { params: { page: 1 } });
Summary
Moving from Axios to alova is not about "switching HTTP libraries." It's about treating requests as composable scenarios rather than one-shot operations you wire up manually. Whether this abstraction is valuable depends on your project's specific needs — the code reduction is real, but so are the trade-offs.
Top comments (0)