Два варианта вызова API в React-компоненте. Какой правильный?
middle
correct_vs_wrong
#328
Вариант 1
function Orders() {
const [orders, setOrders] = useState<Order[]>([]);
useEffect(() => {
api.get('/orders').then(r => setOrders(r.data));
}, []);
return <ul>{orders.map(o => <li key={o.id}>{o.name}</li>)}</ul>;
}
Вариант 2
// С TanStack Query (рекомендую в 2026)
import { useQuery } from '@tanstack/react-query';
function Orders() {
const { data, isLoading, error, refetch } = useQuery({
queryKey: ['orders'],
queryFn: () => api.get<Order[]>('/orders').then(r => r.data),
staleTime: 60_000, // 1 минуту считаем данные свежими
retry: 2,
});
if (isLoading) return <Spinner />;
if (error) return <Err onRetry={refetch} msg={error.message} />;
return <ul>{data!.map(o => <li key={o.id}>{o.name}</li>)}</ul>;
}
// Или вручную (без TanStack)
function OrdersManual() {
const [data, setData] = useState<Order[] | null>(null);
const [error, setError] = useState<string | null>(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
const ctrl = new AbortController();
setLoading(true); setError(null);
api.get<Order[]>('/orders', { signal: ctrl.signal })
.then(r => setData(r.data))
.catch(e => { if (e.name !== 'CanceledError') setError(e.message); })
.finally(() => setLoading(false));
return () => ctrl.abort();
}, []);
if (loading) return <Spinner />;
if (error) return <Err msg={error} />;
return <ul>{(data ?? []).map(o => <li key={o.id}>{o.name}</li>)}</ul>;
}
Чтобы решить вопрос и сохранить попытку — войди.