125 lines
8.4 KiB
Markdown
125 lines
8.4 KiB
Markdown
|
|
# Хуки API (React Hooks)
|
|||
|
|
|
|||
|
|
> В проекте для работы с API-хуками используется только React и библиотека SWR для получения данных (GET-запросы).
|
|||
|
|
> В этом разделе собраны основные правила и рекомендации по созданию и оформлению хуков для работы с API. Следуйте этим принципам, чтобы обеспечить чистую архитектуру, переиспользуемость и единый стиль работы с API-хуками в проекте.
|
|||
|
|
|
|||
|
|
## Описание и назначение API-хуков
|
|||
|
|
|
|||
|
|
API-хуки предназначены для получения данных с сервера (GET-запросы) и используются в компонентах или других хуках.
|
|||
|
|
В проекте для этого применяется библиотека SWR, которая обеспечивает кэширование, автоматическое обновление и удобную работу с асинхронными запросами.
|
|||
|
|
|
|||
|
|
**Fetcher** — это функция, которую использует SWR для выполнения запроса к API. В проекте fetcher обычно экспортируется из файла клиента (например, `backendFetcher` из `shared/api/backend/client.ts`) и инкапсулирует логику обращения к конкретному API-клиенту.
|
|||
|
|
|
|||
|
|
**API-клиент** — это отдельный модуль (папка), отвечающий за взаимодействие с конкретным внешним или внутренним API.
|
|||
|
|
API-клиент включает:
|
|||
|
|
- инициализацию экземпляра HTTP-клиента (например, Axios),
|
|||
|
|
- настройку базового URL, интерцепторов и общих обработчиков ошибок,
|
|||
|
|
- организацию всех сущностей и методов для работы с этим API (например, users, auth, orders и т.д.),
|
|||
|
|
- экспорт всех функций, типов и fetcher через индексные файлы.
|
|||
|
|
|
|||
|
|
Каждый API-клиент размещается в папке `src/shared/api/<client-name>/` и имеет собственную структуру согласно архитектуре проекта.
|
|||
|
|
|
|||
|
|
## Структура
|
|||
|
|
- Каждый API-хук размещается в отдельном файле с именем `use-<method-name>.hook-api.ts` в папке `hooks/api/<client-name>/` на своём уровне абстракции согласно архитектуре проекта.
|
|||
|
|
- Имя хука — в стиле camelCase с префиксом `use` (например, `useGetUser`).
|
|||
|
|
- Для сложных возвращаемых структур используйте отдельные типы или интерфейсы, размещая их в папке `types/` на своём уровне абстракции.
|
|||
|
|
|
|||
|
|
## Именование
|
|||
|
|
- Соблюдайте [правила именования файлов и папок](#правила-именования-файлов-и-папок):
|
|||
|
|
- Файл хука — `use-<method-name>.hook-api.ts` (kebab-case).
|
|||
|
|
- Имя хука — camelCase с префиксом `use`.
|
|||
|
|
|
|||
|
|
## Требования
|
|||
|
|
- Хук должен быть строго типизирован: все параметры, возвращаемые значения и внутренние переменные должны иметь явные типы.
|
|||
|
|
- Для получения данных используйте только SWR.
|
|||
|
|
- Не дублируйте логику между хуками — общие части выносите в shared.
|
|||
|
|
- Не используйте side-effects вне useEffect/useLayoutEffect.
|
|||
|
|
|
|||
|
|
## Типизация
|
|||
|
|
- Всегда явно указывайте типы для всех параметров, возвращаемых значений и состояния внутри хука.
|
|||
|
|
- Придерживайтесь [общих правил типизации проекта](#общие-правила-типизации).
|
|||
|
|
- Не используйте неявное приведение типов и не полагайтесь на автоматический вывод, если это может снизить читаемость или безопасность.
|
|||
|
|
|
|||
|
|
## Документирование
|
|||
|
|
- Документируйте только назначение хука (описание), строго по [правилам документирования кода](#правило-для-документирования-кода).
|
|||
|
|
|
|||
|
|
## Экспорт
|
|||
|
|
- Экспортируйте хук только именованным экспортом через `index.ts` слоя/компонента.
|
|||
|
|
|
|||
|
|
## Пример API хука
|
|||
|
|
|
|||
|
|
```ts
|
|||
|
|
// use-get-me.hook-api.ts
|
|||
|
|
import useSWR from 'swr';
|
|||
|
|
import { backendFetcher } from 'shared/api/backend/client';
|
|||
|
|
import { UserDto } from 'shared/api/backend/entities/users/get-me.api';
|
|||
|
|
|
|||
|
|
/**
|
|||
|
|
* Хук для получения информации о текущем пользователе.
|
|||
|
|
*/
|
|||
|
|
export const useGetMe = () => {
|
|||
|
|
const { data, error, isLoading } = useSWR<UserDto>('/users/me', backendFetcher);
|
|||
|
|
|
|||
|
|
return {
|
|||
|
|
data,
|
|||
|
|
error,
|
|||
|
|
isLoading,
|
|||
|
|
};
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Пример использования хука в компоненте
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
import React from 'react';
|
|||
|
|
import { useGetMe } from 'shared/hooks/api/backend/use-get-me.hook-api';
|
|||
|
|
|
|||
|
|
export const UserInfo: React.FC = () => {
|
|||
|
|
const { data, error, isLoading } = useGetMe();
|
|||
|
|
|
|||
|
|
if (isLoading) {
|
|||
|
|
return <div>Загрузка...</div>;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (error) {
|
|||
|
|
return <div>Ошибка загрузки данных</div>;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!data) {
|
|||
|
|
return <div>Нет данных о пользователе</div>;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<div>
|
|||
|
|
<div>Имя: {data.name}</div>
|
|||
|
|
<div>Email: {data.email}</div>
|
|||
|
|
</div>
|
|||
|
|
);
|
|||
|
|
};
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## Чек-лист для создания API-хука
|
|||
|
|
|
|||
|
|
- [ ] Для каждого GET-запроса создан отдельный хук.
|
|||
|
|
- [ ] Хук размещён в `hooks/api/<client-name>/use-<method-name>.hook-api.ts` на своём уровне абстракции согласно архитектуре проекта.
|
|||
|
|
- [ ] Именование файлов и сущностей соответствует [правилам именования файлов и папок](#правила-именования-файлов-и-папок).
|
|||
|
|
- [ ] Используется SWR для получения данных.
|
|||
|
|
- [ ] Все параметры, возвращаемые значения и внутренние переменные строго типизированы.
|
|||
|
|
- [ ] Нет дублирования логики между хуками.
|
|||
|
|
- [ ] Не используются side-effects вне useEffect/useLayoutEffect.
|
|||
|
|
- [ ] Документировано только назначение хука (см. [правила документирования кода](#правило-для-документирования-кода)).
|
|||
|
|
- [ ] Нет неиспользуемого или невалидного кода.
|
|||
|
|
- [ ] Экспорт только именованный через индексный файл.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Чек-лист для использования API-хука
|
|||
|
|
|
|||
|
|
- [ ] Импортируется только нужный хук через публичные экспорты (`index.ts`).
|
|||
|
|
- [ ] Использование хука строго по назначению (только для получения данных).
|
|||
|
|
- [ ] Если требуется получить данные через GET-запрос в компоненте — обязательно используется соответствующий API-хук.
|
|||
|
|
**Запрещено вызывать GET-методы API напрямую в компонентах, только через хуки.**
|
|||
|
|
- [ ] Обработка состояний загрузки, ошибки и данных реализована корректно.
|
|||
|
|
- [ ] Не происходит дублирования логики, связанной с получением данных.
|
|||
|
|
- [ ] Нет неиспользуемого или невалидного кода.
|