useAxios: настраиваемый хук для вызова API с помощью библиотеки Axios
Фронтенд-приложения не завершены, если не используют вызовы API. Разработчик Йогини Бэнде с помощью библиотеки Axios создала для этого простой настраиваемый хук под названием useAxios.
Библиотека Axios представляет собой HTTP-клиент, основанный на промисах и предназначенный для браузеров и для Node.js. Чтобы выполнить хук понадобится:
- Выполнить вызов API из компонента с помощью Axios;
- Добавить состояние для API, загрузки и ошибки;
- Создать хук для вызова API, с помощью всего вышеперечисленного;
- Сделать хук динамическим, чтобы вызывать все типы методов API.
1. Простой вызов API из компонента
Для этого понадобится API posts jsonplaceholder. Как правило, все API-интерфейсы приложения имеют один и тот же базовый URL-адрес. Сначала необходимо настроить базовый URL-адрес для Axios, поэтому нет необходимости постоянно его передавать. Если используется более одного базового URL-адреса, HTTP-клиент поддерживает его путем создания экземпляров. Это можно проверить в документации.
В компоненте приложения вызываем get API, чтобы получить список обращений. Для этого используем хук useEffect. Базовый вызов API из компонента приложения будет выглядеть примерно так:
//App Component
import { useEffect } from 'react';
import axios from 'axios';
axios.defaults.baseURL = 'https://jsonplaceholder.typicode.com';
const App = () => {
const fetchData = () => {
axios
.get('/posts')
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
};
useEffect(() => {
fetchData();
}, []);
return (
<div className='app'>
//do something
</div>
);
};
export default App;
Вызов API, произведенный выше, прост. Был использован axious.get для вызова API. Так как базовый URL уже настроен, методу axious передается конкретный путь.
2. Добавление разных состояний к вызову API
До сих пор ответ от API просто регистрировался. Теперь можно воспользоваться состояниями реакции, чтобы сохранить ответ и ошибку, если что-то из этого произошло. Кроме того, добавляем состояние загрузки для условного отображения загрузчиков на странице.
// App Component
import { useState, useEffect } from 'react';
import axios from 'axios';
axios.defaults.baseURL = 'https://jsonplaceholder.typicode.com';
const App = () => {
const [response, setResponse] = useState(null);
const [error, setError] = useState('');
const [loading, setloading] = useState(true);
const fetchData = () => {
axios
.get('/posts')
.then((res) => {
setResponse(res.data);
})
.catch((err) => {
setError(err);
})
.finally(() => {
setloading(false);
});
};
useEffect(() => {
fetchData();
}, []);
return (
<div className='app'>
//do something
</div>
);
};
export default App;
3. Создание кастомного хука
Кастомный хук — это просто еще один компонент, который возвращает значения вместо JSX. Побольше узнать о них можно здесь.
Далее копируем логику вызова API из компонента приложения в кастомный хук. Первый черновик useAxios будет выглядеть так:
// useAxios hook (first draft)
import { useState, useEffect } from 'react';
import axios from 'axios';
axios.defaults.baseURL = 'https://jsonplaceholder.typicode.com';
const useAxios = () => {
const [response, setResponse] = useState(null);
const [error, setError] = useState('');
const [loading, setloading] = useState(true);
const fetchData = () => {
axios
.get('/posts')
.then((res) => {
setResponse(res.data);
})
.catch((err) => {
setError(err);
})
.finally(() => {
setloading(false);
});
};
useEffect(() => {
fetchData();
}, []);
// custom hook returns value
return { response, error, loading };
};
export default useAxios;
Хук будет возвращать три значения: загрузку, ответ и ошибку. Нюанс в том, что созданный хук не динамический. Если нужно изменить путь к API или, сделать вызов post вместо get, пока ничего не получится.
4. Придание хуку динамичности
Чтобы сделать хук динамическим, можно создать переменную для URL-адреса и передать ее в качестве опоры хуку. У клиента axious может быть любой метод из get, put, post и delete, следовательно понадобится переменная для имени метода. С помощью пути и методов добавляем две переменные, которые можно использовать для передачи тела и заголовков в запрос. После выполнения вышеописанных действий хук будет выглядеть так:
// useAxios hook
import { useState, useEffect } from 'react';
import axios from 'axios';
axios.defaults.baseURL = 'https://jsonplaceholder.typicode.com';
const useAxios = ({ url, method, body = null, headers = null }) => {
const [response, setResponse] = useState(null);
const [error, setError] = useState('');
const [loading, setloading] = useState(true);
const fetchData = () => {
axios[method](url, JSON.parse(headers), JSON.parse(body))
.then((res) => {
setResponse(res.data);
})
.catch((err) => {
setError(err);
})
.finally(() => {
setloading(false);
});
};
useEffect(() => {
fetchData();
}, [method, url, body, headers]);
return { response, error, loading };
};
export default useAxios;
Хук useAxios готов. Теперь можно использовать его в компоненте приложения и создать с его помощью новый пост.
// App Component
const App = () => {
const { response, loading, error } = useAxios({
method: 'post',
url: '/posts',
headers: JSON.stringify({ accept: '*/*' }),
body: JSON.stringify({
userId: 1,
id: 19392,
title: 'title',
body: 'Sample text',
}),
});
const [data, setData] = useState([]);
useEffect(() => {
if (response !== null) {
setData(response);
}
}, [response]);
return (
<div className='App'>
<h1>Posts</h1>
{loading ? (
<p>loading...</p>
) : (
<div>
{error && (
<div>
<p>{error.message}</p>
</div>
)}
<div>{data && <p>{data.id}</p>}</div>
</div>
)}
</div>
);
};
export default App;
Автор метода утверждает, что это самая простая версия хука useAxios и к нему при необходимости можно добавлять дополнительные настройки.
Чтобы сделать хук более мощным пользователи посоветовали Йогини Бэнде обернуть хук в React Query. Как это сделать написано здесь.
При возникновении ошибки зависимости, добавьте axiousParams в пустой список во втором параметре хука useEffect.

Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: