Home
/
Framework Examples
/
React
React JSON API examples (useEffect, SWR, React Query)
Last updated 2026-05-20
When to use this
Use this when you are wiring a JSON API into a React UI. The three patterns below — vanilla useEffect, SWR, React Query — give you progressively more caching, dedupe, and refetch logic for free.
Example JSON
Reference JSON payload returned by /users/1 (used in every snippet below).
{
"id": 1,
"firstName": "Emily",
"lastName": "Johnson",
"email": "emily.johnson@x.example",
"username": "emilys",
"image": "https://jsonexamples.com/image/200?text=User+1",
"address": {
"address": "626 Main Street",
"city": "Phoenix",
"state": "OK",
"postalCode": "29920",
"country": "United States"
}
}
Request examples
useEffect + fetch
SWR
React Query
Paginated list with React Query
Mutate + invalidate
Copy
import { useEffect, useState } from 'react';
function useUser(id) {
const [user, setUser] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
let alive = true;
fetch('https://jsonexamples.com/users/' + id)
.then(r => r.ok ? r.json() : Promise.reject(r.status))
.then(d => { if (alive) setUser(d); })
.catch(err => alive && setError(err));
return () => { alive = false; };
}, [id]);
return { user, error };
}
Copy
import useSWR from 'swr';
const fetcher = url => fetch(url).then(r => r.json());
function UserCard({ id }) {
const { data, error } = useSWR('https://jsonexamples.com/users/' + id, fetcher);
if (error) return <p>failed</p>;
if (!data) return <p>loading...</p>;
return <p>{data.firstName} {data.lastName}</p>;
}
Copy
import { useQuery } from '@tanstack/react-query';
function UserCard({ id }) {
const { data, isLoading, error } = useQuery({
queryKey: ['user', id],
queryFn: () => fetch('https://jsonexamples.com/users/' + id).then(r => r.json()),
});
if (isLoading) return <p>loading...</p>;
if (error) return <p>failed</p>;
return <p>{data.firstName} {data.lastName}</p>;
}
Copy
function Users() {
const [skip, setSkip] = useState(0);
const { data } = useQuery({
queryKey: ['users', skip],
queryFn: () => fetch('https://jsonexamples.com/users?skip=' + skip + '&limit=20').then(r => r.json()),
keepPreviousData: true,
});
if (!data) return null;
return <>
<ul>{data.users.map(u => <li key={u.id}>{u.firstName}</li>)}</ul>
<button onClick={() => setSkip(s => s + 20)} disabled={skip + 20 >= data.total}>Next</button>
</>;
}
Copy
const qc = useQueryClient();
const addUser = useMutation({
mutationFn: body => fetch('https://jsonexamples.com/users/add', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body)
}).then(r => r.json()),
onSuccess: () => qc.invalidateQueries({ queryKey: ['users'] })
});
Try the live endpoint
Click below to call /users/1 from your browser.
Call /users/1
// click the button to populate this block
Common variations
Optimistic update with SWR
{
"snippet": "import useSWR, { mutate } from 'swr';\n\nasync function toggleTodo(id, completed) {\n mutate('/todos/' + id, prev => ({ ...prev, completed }), false);\n await fetch('/todos/' + id, { method: 'PATCH', body: JSON.stringify({ completed }) });\n mutate('/todos/' + id);\n}"
}
Copy link to this example
https://jsonexamples.com/framework-examples/react