Axios — это библиотека JS, предоставляющая простой в применении интерфейс для выполнения HTTP-запросов в браузере и на стороне сервера. Она развернута на стандарте Promise API и предназначена для работы с асинхронными запросами.
Библиотека широко используется в различных проектах, включая React, Vue.js, Angular и другие фреймворки. Она позволяет разработчикам легко взаимодействовать с API и обрабатывать данные, получаемые от сервера.
Список преимуществ применения данной библиотеки в React:
Стоит сказать о требованиях, достаточных для работы с рассматриваемой библиотекой:
create-react-app
;В статье мы рассмотрим, как использовать Axios с React и приведем несколько примеров его применения.
Шаг 1. Перед началом работы с Axios необходимо выбрать рабочий проект:
cd project_name
Либо организовать новый, а затем перейти в него:
npx create-react-app project_name
cd project_name
Создадим React-приложение с названием timeweb
. Результаты создания продемонстрированы на картинке ниже.
Шаг 2. Далее необходимо поставить библиотеку, воспользовавшись пакетным менеджером npm
. Для этого выполним следующую команду в терминале:
npm install axios
Шаг 3. По окончанию загрузки необходимо импортировать библиотеку в компонент, требующий ее использования:
import axios from 'axios';
После успешной установки и импортирования библиотеки Axios в ваше React-приложение вы можете начать взаимодействие с ней.
Чтобы отправить 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. Проверим результат запроса. Он представлен на картинке ниже.
Обратите внимание, что в данном примере и во всех остальных используется API https://jsonplaceholder.typicode.com
, который предоставляет фейковые данные с целью тестирования. Вам следует заменить его на тот, который будет использоваться в проекте.
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. Проверим результат работы компонента. Он представлен на картинке ниже.
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. Проверим результат работы компонента. Он представлен на картинке ниже.
Чтобы отправить 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. Проверим результат работы компонента. Он представлен на картинке ниже.
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. Проверим результат работы компонента. Он представлен на картинке ниже.
Кроме того, рассматриваемая библиотека также предоставляет статический метод 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 — это инструменты для управления асинхронными операциями в 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-cache-adapter
или написать свой кэширующий обработчик.
Иногда мы можем получить все необходимые данные с сервера в одном запросе, вместо того, чтобы отправлять несколько запросов на получение разных данных. Например, мы можем объединить несколько запросов в один и получить все необходимые данные с сервера.
Как мы уже упоминали, отмена запросов может быть полезной, когда мы отправляем много запросов или когда пользователь быстро переключается между страницами. Неотмененные запросы могут привести к перегрузке сервера и замедлению производительности приложения.
В некоторых случаях мы можем отложить загрузку данных до тех пор, пока они не понадобятся пользователю. Например, мы можем загружать данные только когда пользователь прокручивает страницу или открывает модальное окно. Это может уменьшить количество запросов и ускорить производительность приложения.
Интерсепторы позволяют нам манипулировать запросами и ответами, перед тем как они будут отправлены или обработаны. Мы можем использовать их для логирования запросов и ответов, обработки ошибок и т.д. Однако, использование слишком большого количества интерсепторов может снизить производительность приложения.
Возможно использовать библиотеки мемоизации, такие как React.memo
или useMemo
, чтобы избежать повторного рендеринга компонентов, которые не изменились. Это может сократить число запросов к серверу и повысить производительность.
Axios — это библиотека для отправки HTTP-запросов, которая может быть использована с React. В этой статье мы рассмотрели основы использования Axios и привели несколько примеров работы с ним.