Давайте дружить в Телеграме: рассказываем про новые фичи, общаемся в комментах, прислушиваемся к вашим идеям Подписаться

Использование Axios с React

Илья Ушаков
Илья Ушаков
Технический писатель
21 апреля 2023 г.
2588
20 минут чтения
Средний рейтинг статьи: 3

Axios — это библиотека JS, предоставляющая простой в применении интерфейс для выполнения HTTP-запросов в браузере и на стороне сервера. Она развернута на стандарте Promise API и предназначена для работы с асинхронными запросами. 

Библиотека широко используется в различных проектах, включая React, Vue.js, Angular и другие фреймворки. Она позволяет разработчикам легко взаимодействовать с API и обрабатывать данные, получаемые от сервера.

Список преимуществ применения данной библиотеки в React:

  • Простота применения: Имеет простой и легко понятный интерфейс, который делает его ясным в применении даже среди новичков. Это позволяет разработчикам быстро отправлять HTTP-запросы на сервер и получать от него ответы.
  • Универсальность: Поддерживает не только браузеры, но и Node.js, что делает его идеальным выбором для применения на клиентской и на серверной стороне в проектах на React.
  • Поддержка Promises: Возвращает объект Promises, что делает его идеальным для работы с современным синтаксисом JavaScript и облегчает обработку асинхронных операций.
  • Интерсепторы: Позволяет использовать интерсепторы, чтобы запросы и ответы обрабатывались до их отправки и после получения. Это полезно для добавления заголовков, обработки ошибок и многого другого.
  • Отмена запроса: Библиотека допускает отмену запросов, что позволяет улучшить производительность приложения и предотвратить лишние запросы.
  • Поддержка заголовков и параметров запроса: Позволяет добавлять заголовки и параметры запроса, что полезно при передаче информации на сервер.
  • Широкий функционал: Поддерживает все основные методы HTTP-запросов: GET, POST, PUT, DELETE и т.д. Он также поддерживает множество типов данных, таких как JSON, формы и текст.
  • Обработка ошибок: Имеет встроенную обработку ошибок, что позволяет определять и обрабатывать ошибки, возникающие во время выполнения запросов.

Стоит сказать о требованиях, достаточных для работы с рассматриваемой библиотекой:

  • Node.js 14 версии и позднее;
  • Проект на React, организованный инструментом create-react-app;
  • Базовые знания JS, HTML и CSS.

В статье мы рассмотрим, как использовать Axios с React и приведем несколько примеров его применения.

Установка Axios и импортирование в проект

Шаг 1. Перед началом работы с Axios необходимо выбрать рабочий проект:

cd project_name

Либо организовать новый, а затем перейти в него:

npx create-react-app project_name
cd project_name

Создадим React-приложение с названием timeweb. Результаты создания продемонстрированы на картинке ниже.

Image1

Шаг 2. Далее необходимо поставить библиотеку, воспользовавшись пакетным менеджером npm. Для этого выполним следующую команду в терминале:

npm install axios

Шаг 3. По окончанию загрузки необходимо импортировать библиотеку в компонент, требующий ее использования:

import axios from 'axios';

После успешной установки и импортирования библиотеки Axios в ваше React-приложение вы можете начать взаимодействие с ней.

GET-запрос

Чтобы отправить GET-запрос, используется метод axios.get(), который принимает один параметр – адрес интернет-ресурса. Он не должен использоваться для отправки конфиденциальных данных, так как они могут быть видны в адресной строке браузера и логах сервера.

Для начала разработаем необходимый для реализации компонент. 

Шаг 1. Перейдем из каталога приложения в директорию src.

cd src

Шаг 2. Далее создаем файл с расширением .js:

nano Test1.js

Шаг 3. Теперь переходим к написанию кода:

import React, { useEffect, useState } from "react";
import axios from "axios";

function Test1() {
  const [data, setData] = useState([]);

  useEffect(() => {
    axios
      .get("https://jsonplaceholder.typicode.com/users")
      .then((response) => {
        setData(response.data);
      })
      .catch((error) => {
        console.log(error);
      });
  }, []);

  return (
    <div>
      <h1>Список пользователей:</h1>
      <ul>
        {data.map((user) => (
          <li key={user.id}>
            {user.name} ({user.email})
          </li>
        ))}
      </ul>
    </div>
  );
}

export default Test1;

В данном примере Test1 отправляет GET-запрос на указанный сервис и отображает список пользователей на странице. В компоненте используются два хука: 

  • useEffect для выполнения запроса; 
  • useState для хранения данных, полученных от API. 

Хук — это функция, которая позволяет использовать состояние и другие возможности React в функциональных компонентах. Если запрос не получилось отправить или обработать, то мы выводим ошибку в консоль.

Шаг 4. Проверим результат запроса. Он представлен на картинке ниже.

Image5

Обратите внимание, что в данном примере и во всех остальных используется API https://jsonplaceholder.typicode.com, который предоставляет фейковые данные с целью тестирования. Вам следует заменить его на тот, который будет использоваться в проекте.

POST-запрос

POST-запросы используются для отправки данных на сервер, например, отправки формы с данными пользователя, отправки изображений или других файлов, а также для создания или обновления записей в базе данных.

POST-запросы могут быть безопасными, если они не изменяют состояние сервера, но они не являются идемпотентными, что означает, что при повторном отправлении может произойти изменение состояния сервера. Для идемпотентности они могут содержать специальный заголовок, например, Idempotency-Key, который позволяет серверу определять, был ли запрос отправлен ранее.

POST-запросы также могут быть защищены с помощью токенов CSRF, чтобы предотвратить их подделку со стороны злоумышленников.

Чтобы отправить POST-запрос, необходимо вызвать метод post() и передать ему данные и адрес интернет-ресурса, на который необходимо их отправить. 

Шаг 1. Откроем ранее созданный файл для редактирования:

nano Test1.js

Шаг 2. Напишем новый код:

import React, { useState } from "react";
import axios from "axios";

function Test1() {
  const [data, setData] = useState({ name: "", email: "" });
  const [response, setResponse] = useState("");

  const handleChange = (event) => {
    setData({ ...data, [event.target.name]: event.target.value });
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    axios
      .post("https://jsonplaceholder.typicode.com/users", data)
      .then((response) => {
        setResponse(response.data);
      })
      .catch((error) => {
        console.log(error);
      });
  };

  return (
    <div>
      <h1>Отправка данных на сервер</h1>
      <form onSubmit={handleSubmit}>
        <label>
          Имя:
          <input
            type="text"
            name="name"
            value={data.name}
            onChange={handleChange}
          />
        </label>
        <br />
        <label>
          Email:
          <input
            type="email"
            name="email"
            value={data.email}
            onChange={handleChange}
          />
        </label>
        <br />
        <button type="submit">Отправить</button>
      </form>
      {response && (
        <p>
          Данные успешно отправлены: {response.name} ({response.email})
        </p>
      )}
    </div>
  );
}

export default Test1;

В этом примере мы также применили useState для хранения данных, введенных пользователем в форме, и данных, полученных от API. Мы также создали две функции: 

  • handleChange для обновления состояния формы при изменении пользователем данных;
  • handleSubmit для отправки POST-запроса при передаче формы.

Когда форма передается, мы отправляем POST-запрос и обрабатываем полученные данные, используя метод setResponse. Если запрос не удалось отправить или обработать, то мы выводим ошибку в консоль.

Шаг 3. Проверим результат работы компонента. Он представлен на картинке ниже.

Image2

PUT-запрос

PUT-запросы отправляют данные в теле запроса на сервер, где они заменяют существующие данные ресурса. Они часто используются для обновления информации о пользователе, обновления контента на веб-страницах или для обновления данных в базе данных.

Чтобы отправить PUT-запрос, необходимо вызвать метод put() и передать ему данные и URL-адрес ресурса, на который необходимо их отправить. 

Шаг 1. Откроем файл компонента для редактирования:

nano Test1.js

Шаг 2. Снова перепишем код файла Test1.js:

import React, { useState } from "react";
import axios from "axios";

const Test1 = () => {
  const [postData, setPostData] = useState({ id: "", title: "", body: "" });
  const [putData, setPutData] = useState({ id: "", title: "", body: "" });

  const handleInputChange = (event) => {
    setPostData({ ...postData, [event.target.name]: event.target.value });
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    axios
      .put(`https://jsonplaceholder.typicode.com/posts/${postData.id}`, {
        title: postData.title,
        body: postData.body,
      })
      .then((response) => {
        setPutData(response.data);
        console.log(response);
      })
      .catch((error) => {
        console.log(error);
      });
  };

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <div>
          <label htmlFor="id">Уникальный номер: </label>
          <input
            type="text"
            name="id"
            value={postData.id}
            onChange={handleInputChange}
          />
        </div>
        <div>
          <label htmlFor="title">Заголовок: </label>
          <input
            type="text"
            name="title"
            value={postData.title}
            onChange={handleInputChange}
          />
        </div>
        <div>
          <label htmlFor="body">Основная информация: </label>
          <input
            type="text"
            name="body"
            value={postData.body}
            onChange={handleInputChange}
          />
        </div>
        <button type="submit">Обновить данные</button>
      </form>
      <div>
        <p>Ответ:</p>
        <p>Уникальный номер:: {putData.id}</p>
        <p>Заголовок: {putData.title}</p>
        <p>Основная информация: {putData.body}</p>
      </div>
    </div>
  );
};

export default Test1;

Здесь используется useState для управления двумя состояниями: 

  • postData содержит данные для отправки в PUT-запросе; 
  • putData содержит полученные в ответ на запрос данные.

Также определяем две функции: 

  • handleInputChange — обновляет состояние postData, при добавлении пользователем данных в форму;
  • handleSubmit — посылает PUT-запрос и обновляет состояние putData.

Наконец, мы отображаем полученные данные в putData после успешного выполнения запроса.

Шаг 3. Проверим результат работы компонента. Он представлен на картинке ниже.

Image4

DELETE-запрос

Чтобы отправить DELETE-запрос, нужно вызвать метод delete() и передать ему URL-адрес ресурса для удаления. После получения запроса сервер проверяет, есть ли указанный ресурс на сервере, и если он есть, то удаляет его. Если ресурса на сервере нет, он может вернуть ошибку 404 «Не найдено».

Шаг 1. Откроем файл компонента для редактирования:

nano Test1.js

Шаг 2. Снова перепишем код Test1.js:

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

const Test1 = () => {
  const [postId, setPostId] = useState(null);
  const [response, setResponse] = useState(null);

  const handleDelete = () => {
    axios.delete(`https://jsonplaceholder.typicode.com/posts/${postId}`)
      .then(res => setResponse(res))
      .catch(err => setResponse(err));
  }

  return (
    <div>
      <input type="number" placeholder="Enter Post ID" onChange={(e) => setPostId(e.target.value)} />
      <button onClick={handleDelete}>Delete Post</button>
      {response && (
        <div>
          <h2>Response</h2>
          <p>Status: {response.status}</p>
          <p>Data: {JSON.stringify(response.data)}</p>
        </div>
      )}
    </div>
  );
}

export default Test1;

В этом компоненте мы создали форму, где пользователь может ввести ID записи, которую он хочет удалить, и отправить запрос на удаление при помощи метода axios.delete(). Мы также обработали успешный ответ и ошибки при помощи методов then() и catch() соответственно.

Шаг 3. Проверим результат работы компонента. Он представлен на картинке ниже.

Image6

Обработка ошибок

Axios предоставляет удобный способ обработки ошибок, возникающих при отправке HTTP-запросов. then() и catch() принимают функции, которые будут выполнены в зависимости от статуса выполнения запроса (выполнен или произошла ошибка). 

Шаг 1. Откроем файл компонента для редактирования:

nano Test1.js

Шаг 2. В очередной раз перепишем код файла Test1.js:

import React, { useState } from "react";
import axios from "axios";

const Test1 = () => {
  const [error, setError] = useState(null);

  const handleButtonClick = () => {
    axios
      .get("https://jsonplaceholder.typicode.com/posts/invalid-url")
      .then((response) => {
        console.log(response);
      })
      .catch((error) => {
        setError(error);
      });
  };

  return (
    <div>
      <button onClick={handleButtonClick}>Отправить GET-запрос</button>
      {error && (
        <div>
          <h2>Сообщение об ошибке:</h2>
          <p>{error.message}</p>
        </div>
      )}
    </div>
  );
};

export default Test1;

В примере выше создается состояние error. Оно позволяет отслеживать ошибки, которые возникают при отправке запросов. Затем мы создаем функцию handleButtonClick, которая отправляет GET-запрос на неверный URL и, в случае возникновения ошибки, использует метод setError для обновления состояния error с сообщением об ошибке.

Возвращаемое значение компонента содержит кнопку и блок данных. Кнопка вызывает функцию handleButtonClick, а блок отображается только в том случае, если error не является нулевым или ложным. В блоке мы выводим сообщение об ошибке, используя свойство message объекта ошибки.

Шаг 3. Проверим результат работы компонента. Он представлен на картинке ниже.

Image3

Кроме того, рассматриваемая библиотека также предоставляет статический метод isCancel(), который может быть использован для проверки, является ли ошибка результатом отмены запроса. Это может быть полезно, если вы используете CancelToken или AbortController для отмены запроса. Об этом мы поговорим немного позже.

Создание базового экземпляра

Базовый экземпляр — это объект, который содержит конфигурационные параметры и методы для создания запросов.

Чтобы организовать базовый экземпляр необходимо использовать create() из рассматриваемой библиотеки и передать ей объект с настройками. В объекте настроек можно указать общий URL для всех запросов, заголовки, авторизационный токен и другие параметры.

Например, если в приложении нужно отправлять запросы к API с общим адресом ресурса, можно создать базовый экземпляр в директории src следующим образом.

Шаг 1. Создадим файл с расширением .js:

nano basic.js

Шаг 2. Далее напишем код:

import axios from 'axios';

const exemplar = axios.create({
  baseURL: 'https://jsonplaceholder.typicode.com/',
});

export default exemplar;

Шаг 3. Импортирование экземпляра рассмотрим на примере из раздела «Обработка ошибок»:

import React, { useState } from "react";
import axios from "axios";
import exemplar from "./basic";

const Test1 = () => {
  const [error, setError] = useState(null);

  const handleButtonClick = () => {
    exemplar
      .get("invalid-url")
      .then((response) => {
        console.log(response);
      })
      .catch((error) => {
        setError(error);
      });
  };

...

export default Test1;

Изменения — в строках:

    exemplar
      .get("invalid-url")

и

import exemplar from "./basic";

Использование async и await

Async и Await — это инструменты для управления асинхронными операциями в JavaScript. Они могут значительно упростить код, связанный с обработкой ответов на запросы с помощью Axios в React.

Для использования данных инструментов вам нужно сначала определить функцию, которая будет вызываться асинхронно. Затем вы можете использовать ключевое слово await, чтобы вызвать функцию Axios и дождаться, пока она выполнит запрос.

Перепишем код из раздела про GET-запрос:

import React, { useEffect, useState } from "react";
import axios from "axios";

function Test1() {
    const [data, setData] = useState([]);

    useEffect(() => {
        async function asyncFunction() {
            try {
                const response = await axios.get("https://jsonplaceholder.typicode.com/users");
                setData(response.data);
            } catch (error) {
                console.log(error);
            }
        }
        asyncFunction();
    }, []);

return (
<div>
    <h1>Список пользователей:</h1>
    <ul>
        {data.map((user) => (
        <li key={user.id}>
            {user.name} ({user.email})
        </li>
        ))}
    </ul>
</div>
);
}

export default Test1;

Создается асинхронная функция asyncFunction, которая ожидает ответа от сервера с помощью ключевого слова await и устанавливает полученные данные с помощью setData

Использование инструментов, описанных в данной главе, позволит пользователям избегать использования колбэков или цепочек then, что делает код более читабельным и понятным. Важно не забывать, что они также требуют наличие обработки ошибок, которая поможет избежать проблемы с блокировкой потока выполнения и неожиданного поведения программы.

Отмена запросов

В приложениях, которые используют Axios для выполнения запросов, может возникнуть необходимость отменять их во время выполнения. 

Вот несколько примеров, когда это может потребоваться:

  • Пользователь нажимает на кнопку «Отмена» во время запроса на сервер, потому что он больше не хочет ждать ответа или перешел на другую страницу.
  • В приложении произошла ошибка, и запрос больше не нужен.
  • Пользователь начал вводить новый запрос, и старый запрос должен быть отменен, чтобы избежать перегрузки сервера запросами.
  • Приложение делает несколько последовательных запросов на сервер, и каждый запрос зависит от предыдущего. Если один из таких запросов завершится с ошибкой, следующие запросы могут стать бесполезными и могут быть отменены, чтобы сократить нагрузку на сервер.

Актуальный способ отмены запросов — использование стандартного API AbortController, который был добавлен в браузеры в ECMAScript 2017. Этот API предоставляет удобный механизм для отмены любых асинхронных операций, включая запросы на сервер.

Чтобы использовать AbortController, необходимо создать экземпляр с таким же именем и передать его в качестве параметра запроса. Для этого используется метод signal.

Создадим экземпляр и объявим его сигнал:

const controller = new AbortController();
const signal = controller.signal;

А затем передадим его в параметры запроса:

axios.get('/user', { signal })
.then((response) => {
  console.log(response.data);
})

А также добавим функцию уведомления об отмене:

if (axios.isCancel(error)) {
    console.log('Запрос отменен', error.message);
}

Чтобы отменить запрос, необходимо вызвать метод abort() на экземпляре. Добавим его в конец кода:

controller.abort();

Использование стандартного API AbortController для отмены запросов вместо CancelToken является более простым и естественным способом, поскольку он уже является стандартным API для отмены асинхронных операций в браузере. Это может также упростить поддержку и совместимость кода с другими библиотеками и фреймворками, которые также используют данный способ.

Оптимизация производительности при использования Axios

В этой главе мы рассмотрим несколько советов по оптимизации производительности при использовании Axios в вашем проекте:

  1. Кэширование запросов

    Часто возникает ситуация, когда мы отправляем один и тот же запрос несколько раз в течение короткого времени. В этом случае, мы можем использовать кэширование запросов, чтобы избежать отправки одного и того же запроса несколько раз. Для этого мы можем использовать библиотеку axios-cache-adapter или написать свой кэширующий обработчик.

  1. Минимизация числа запросов

    Иногда мы можем получить все необходимые данные с сервера в одном запросе, вместо того, чтобы отправлять несколько запросов на получение разных данных. Например, мы можем объединить несколько запросов в один и получить все необходимые данные с сервера.

  1. Отмена запросов

    Как мы уже упоминали, отмена запросов может быть полезной, когда мы отправляем много запросов или когда пользователь быстро переключается между страницами. Неотмененные запросы могут привести к перегрузке сервера и замедлению производительности приложения.

  1. Отложенная загрузка данных

    В некоторых случаях мы можем отложить загрузку данных до тех пор, пока они не понадобятся пользователю. Например, мы можем загружать данные только когда пользователь прокручивает страницу или открывает модальное окно. Это может уменьшить количество запросов и ускорить производительность приложения.

  1. Использование интерсепторов

    Интерсепторы позволяют нам манипулировать запросами и ответами, перед тем как они будут отправлены или обработаны. Мы можем использовать их для логирования запросов и ответов, обработки ошибок и т.д. Однако, использование слишком большого количества интерсепторов может снизить производительность приложения.

  1. Использование мемоизации

    Возможно использовать библиотеки мемоизации, такие как React.memo или useMemo, чтобы избежать повторного рендеринга компонентов, которые не изменились. Это может сократить число запросов к серверу и повысить производительность.

Заключение

Axios — это библиотека для отправки HTTP-запросов, которая может быть использована с React. В этой статье мы рассмотрели основы использования Axios и привели несколько примеров работы с ним.

Зарегистрируйтесь и начните пользоваться
сервисами Timeweb Cloud прямо сейчас

15 лет опыта
Сосредоточьтесь на своей работе: об остальном позаботимся мы
165 000 клиентов
Нам доверяют частные лица и компании, от небольших фирм до корпораций
Поддержка 24/7
100+ специалистов поддержки, готовых помочь в чате, тикете и по телефону