mock_sobes
← Axios / HTTP-клиент во фронтенде
middle correct_vs_wrong #328
Два варианта вызова API в React-компоненте. Какой правильный?
Вариант 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>;
}
Чтобы решить вопрос и сохранить попытку — войди.