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
.
Сообщить об опечатке
Текст, который будет отправлен нашим редакторам: