16. Fetching Data with React Query and Axios
Level: IntermediateDuration: 28m
Why Fetch Data in React?
Most real-world apps need to fetch data—from user profiles to products or posts. React doesn't come with built-in data fetching tools, so we use libraries like Axios or React Query to handle this efficiently.
Fetching Data with Axios
Axios is a lightweight HTTP client used to send API requests. It's easy to set up and works well inside useEffect.
jsx
import { useState, useEffect } from 'react'
import axios from 'axios'
function Users() {
const [users, setUsers] = useState([])
const [loading, setLoading] = useState(true)
const [error, setError] = useState(null)
useEffect(() => {
axios.get('https://jsonplaceholder.typicode.com/users')
.then(res => setUsers(res.data))
.catch(err => setError(err.message))
.finally(() => setLoading(false))
}, [])
if (loading) return <p>Loading...</p>
if (error) return <p>Error: {error}</p>
return (
<ul>
{users.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
)
}
export default UsersThis works, but managing loading states and caching manually can get messy. That’s where React Query comes in.
Fetching Data with React Query
React Query is a powerful tool for managing server state. It automatically handles caching, loading states, refetching and more.
bash
npm install @tanstack/react-query axiosjsx
// main.jsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import App from './App'
const queryClient = new QueryClient()
ReactDOM.createRoot(document.getElementById('root')).render(
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
)jsx
// Users.jsx
import { useQuery } from '@tanstack/react-query'
import axios from 'axios'
const fetchUsers = async () => {
const res = await axios.get('https://jsonplaceholder.typicode.com/users')
return res.data
}
function Users() {
const { data, isLoading, isError, error } = useQuery({
queryKey: ['users'],
queryFn: fetchUsers
})
if (isLoading) return <p>Loading...</p>
if (isError) return <p>Error: {error.message}</p>
return (
<ul>
{data.map(user => <li key={user.id}>{user.name}</li>)}
</ul>
)
}
export default UsersAxios vs React Query
| Feature | Axios Only | React Query |
|---|---|---|
| Caching | ❌ | ✅ |
| Retry Failed Requests | ❌ | ✅ |
| Background Refetch | ❌ | ✅ |
| Easy Loading/Error State | ❌ | ✅ |
| Setup Complexity | Simple | Moderate |
Mini Project Step
In this step, fetch your project feature list from a mock API using React Query and display it instead of hardcoding features in state.
jsx
// src/api/features.js
import axios from 'axios'
export const fetchFeatures = async () => {
const res = await axios.get('https://jsonplaceholder.typicode.com/todos?_limit=3')
return res.data
}jsx
// App.jsx
import { useQuery } from '@tanstack/react-query'
import { fetchFeatures } from './api/features'
function App() {
const { data: features = [], isLoading } = useQuery({
queryKey: ['features'],
queryFn: fetchFeatures
})
return (
<div>
<h1>Project Features</h1>
{isLoading ? <p>Loading...</p> : (
<ul>
{features.map(f => <li key={f.id}>{f.title}</li>)}
</ul>
)}
</div>
)
}
export default App