Loading...
Loading...
Loading...
REST vs GraphQL, fetch patterns, and React Query. Learn how to consume APIs safely with loading and error handling.
REST uses URLs and HTTP methods; GraphQL uses a single endpoint and a query language. Choose based on your API and client needs.
Always check res.ok and handle errors. Use a custom hook or React Query to centralize loading and error state.
// Simple fetch with error handling
async function getUser(id: string) {
const res = await fetch(`/api/users/${id}`, {
headers: { 'Content-Type': 'application/json' },
});
if (!res.ok) {
const error = await res.json().catch(() => ({ message: res.statusText }));
throw new Error(error.message || 'Failed to fetch user');
}
return res.json();
}
// In React with loading and error state
function useUser(id: string | null) {
const [data, setData] = useState(null);
const [error, setError] = useState<Error | null>(null);
const [loading, setLoading] = useState(!!id);
useEffect(() => {
if (!id) return;
let cancelled = false;
setLoading(true);
getUser(id)
.then((user) => { if (!cancelled) setData(user); })
.catch((e) => { if (!cancelled) setError(e); })
.finally(() => { if (!cancelled) setLoading(false); });
return () => { cancelled = true; };
}, [id]);
return { data, error, loading };
}React Query (TanStack Query) handles caching, refetching, and loading/error state for server data. Use queryKey and queryFn for predictable behavior.
// With React Query (recommended for server state)
import { useQuery } from '@tanstack/react-query';
function useUser(id: string | null) {
return useQuery({
queryKey: ['user', id],
queryFn: () => fetch(`/api/users/${id}`).then((r) => {
if (!r.ok) throw new Error('Failed to fetch');
return r.json();
}),
enabled: !!id,
});
}
// In component: automatic loading, error, refetch, cache
function UserProfile({ userId }: { userId: string }) {
const { data, error, isLoading } = useUser(userId);
if (isLoading) return <Skeleton />;
if (error) return <ErrorMessage error={error} />;
return <div>{data.name}</div>;
}Define queries with gql and variables. Apollo Client or urql provide useQuery with caching and normalized cache options.
// GraphQL query example
const GET_USER = gql`
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
posts {
id
title
}
}
}
`;
// With Apollo Client
const { data, loading, error } = useQuery(GET_USER, {
variables: { id: userId },
});