Fetch: loading, erro e sucesso
1 min de leitura
fonte
Uma requisição tem pelo menos três estados visíveis: carregando, sucesso e erro.
Modelar esses estados deixa a interface previsível enquanto o fetch acontece.
import { useEffect, useState } from 'react';
export default function Users() {
const [users, setUsers] = useState([]);
const [status, setStatus] = useState('loading');
const [error, setError] = useState('');
useEffect(() => {
const controller = new AbortController();
async function loadUsers() {
try {
setStatus('loading');
setError('');
const response = await fetch(
'https://jsonplaceholder.typicode.com/users',
{ signal: controller.signal },
);
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
setUsers(data);
setStatus('success');
} catch (err) {
if (err.name === 'AbortError') return;
setError('Não foi possível carregar os usuários.');
setStatus('error');
}
}
loadUsers();
return () => controller.abort();
}, []);
if (status === 'loading') return <p>Carregando...</p>;
if (status === 'error') return <p role="alert">{error}</p>;
return (
<ul>
{users.map((user) => <li key={user.id}>{user.name}</li>)}
</ul>
);
}
O AbortController evita continuar uma requisição que já não interessa quando o
componente sai da tela. Em aplicações maiores, bibliotecas de dados podem cuidar
de cache, deduplicação e revalidação; aqui o objetivo é entender o ciclo básico.
- Loading/erro/sucesso: são estados diferentes da experiência.
response.ok: precisa ser verificado;fetchnão rejeita Promise só por um 404/500.- Abort: é uma forma de limpar trabalho assíncrono que perdeu relevância.
No próximo nó, vamos guardar referências que não precisam causar uma nova renderização.
// Quiz
Por que verificar response.ok após um fetch?
// recursos
// avaliação da trilha
—
ainda sem avaliações