← Назад к вопросам

Как сбросить запрос в Axios?

2.0 Middle🔥 181 комментариев
#Браузер и сетевые технологии

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Что такое отмена запроса в Axios

Отмена запроса нужна для предотвращения использования устаревшего ответа и экономии ресурсов.

Решение 1: AbortController (современный подход)

// Простой пример
const controller = new AbortController();

const request = axios.get('/api/data', {
  signal: controller.signal
});

// Сбросить запрос
controller.abort();

// Это вызовет ошибку
request.catch(error => {
  if (error.name === 'AbortError') {
    console.log('Request was cancelled');
  }
});

Решение 2: Отмена при unmount компонента

import { useEffect, useRef } from 'react';
import axios from 'axios';

export function UserProfile({ userId }) {
  const controllerRef = useRef(new AbortController());

  useEffect(() => {
    const fetchUser = async () => {
      try {
        const response = await axios.get(`/api/users/${userId}`, {
          signal: controllerRef.current.signal
        });
        console.log('User data:', response.data);
      } catch (error) {
        if (error.code === 'ECONNABORTED') {
          console.log('Request cancelled');
        } else {
          console.error('Error:', error);
        }
      }
    };

    fetchUser();

    // Отменить запрос при unmount
    return () => {
      controllerRef.current.abort();
    };
  }, [userId]);

  return <div>Loading user...</div>;
}

Решение 3: Отмена при навигации

import { useEffect, useRef } from 'react';
import axios from 'axios';

export function SearchResults({ searchTerm }) {
  const controllerRef = useRef(null);

  useEffect(() => {
    // Отменить предыдущий запрос
    if (controllerRef.current) {
      controllerRef.current.abort();
    }

    controllerRef.current = new AbortController();

    const fetchResults = async () => {
      try {
        const response = await axios.get('/api/search', {
          params: { q: searchTerm },
          signal: controllerRef.current.signal
        });
        console.log('Results:', response.data);
      } catch (error) {
        if (axios.isCancel(error)) {
          console.log('Previous request cancelled');
        } else {
          console.error('Error:', error);
        }
      }
    };

    if (searchTerm) {
      fetchResults();
    }
  }, [searchTerm]);

  return <div>Search results for: {searchTerm}</div>;
}

Решение 4: Кастомный хук для отмены

import { useEffect, useRef } from 'react';
import axios from 'axios';

export function useAxiosCancel() {
  const controllerRef = useRef(new AbortController());

  useEffect(() => {
    return () => {
      controllerRef.current.abort();
    };
  }, []);

  const getSignal = () => controllerRef.current.signal;

  const reset = () => {
    controllerRef.current.abort();
    controllerRef.current = new AbortController();
  };

  return { signal: getSignal(), reset };
}

// Использование
export function DataComponent() {
  const { signal, reset } = useAxiosCancel();

  useEffect(() => {
    const fetchData = async () => {
      try {
        const response = await axios.get('/api/data', { signal });
        console.log('Data:', response.data);
      } catch (error) {
        console.error('Error:', error);
      }
    };

    fetchData();
  }, [signal]);

  return <button onClick={reset}>Cancel Request</button>;
}

Решение 5: Отмена нескольких запросов

const controller = new AbortController();

const requests = [
  axios.get('/api/users', { signal: controller.signal }),
  axios.get('/api/posts', { signal: controller.signal }),
  axios.get('/api/comments', { signal: controller.signal })
];

// Отменить все сразу
const cancelAll = () => {
  controller.abort();
};

Promise.all(requests)
  .then(responses => {
    console.log('All requests completed');
  })
  .catch(error => {
    if (axios.isCancel(error)) {
      console.log('One or more requests were cancelled');
    }
  });

Решение 6: Практический пример с кнопкой отмены

import { useState, useRef } from 'react';
import axios from 'axios';

export function DataFetcher() {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState(null);
  const controllerRef = useRef(null);

  const fetchData = async () => {
    if (controllerRef.current) {
      controllerRef.current.abort();
    }

    controllerRef.current = new AbortController();
    setLoading(true);
    setError(null);

    try {
      const response = await axios.get('/api/data', {
        signal: controllerRef.current.signal,
        timeout: 10000
      });
      setData(response.data);
    } catch (err) {
      if (axios.isCancel(err)) {
        console.log('Request was cancelled');
      } else {
        setError(err.message);
      }
    } finally {
      setLoading(false);
    }
  };

  const cancelRequest = () => {
    if (controllerRef.current) {
      controllerRef.current.abort();
      setLoading(false);
    }
  };

  return (
    <div>
      <button onClick={fetchData} disabled={loading}>
        {loading ? 'Loading...' : 'Fetch Data'}
      </button>
      {loading && <button onClick={cancelRequest}>Cancel</button>}
      {error && <p style={{ color: 'red' }}>Error: {error}</p>}
      {data && <pre>{JSON.stringify(data, null, 2)}</pre>}
    </div>
  );
}

Ключевые моменты

  1. AbortController - современный стандарт для отмены
  2. signal - передается в запрос для отслеживания
  3. abort() - отменяет запрос
  4. axios.isCancel() - проверяет отмену
  5. Cleanup в useEffect - отменяй при unmount
  6. Timeout - дополнительная защита

Когда использовать

  • При unmount компонента
  • При изменении параметров поиска
  • При навигации на другую страницу
  • При клике пользователя на Cancel
  • При timeout истечении
Как сбросить запрос в Axios? | PrepBro