Перейти к содержанию
Innovialabs

Как организовать структуру React-проекта: папки и соглашения

Практика3 мин

Коротко

Для небольших проектов достаточно группировки по типам файлов, а растущее приложение лучше делить по фичам: всё, что относится к одной функции, лежит в одной папке, а общий код — в shared.

Короткий ответ

У React нет обязательной структуры, поэтому решение остаётся за командой. Работающее правило: маленький проект — группировка по типам, растущий — по фичам. Главное — чтобы любой разработчик за минуту понял, где искать код и куда класть новый.

По типам или по фичам

По типам (type-based) — все компоненты в components/, все хуки в hooks/, все запросы в api/.

По фичам (feature-based) — код группируется по функциям продукта: auth/, cart/, orders/. Внутри фичи лежат её компоненты, хуки, запросы и типы.

КритерийПо типамПо фичам
Порог входаНизкий, понятно сразуНужно договориться о границах фич
Рост проектаПапки разрастаются до сотен файловКаждая фича остаётся компактной
Удаление функцииФайлы разбросаны по проектуУдаляется одна папка
Работа командыЧастые конфликты в общих папкахКоманды работают в своих фичах

Масштабируемое дерево папок

src/
  app/            # точка входа, роутинг, провайдеры
  pages/          # страницы, собирают фичи
  features/
    cart/
      components/
      hooks/
      api.ts
      types.ts
      index.ts    # публичный интерфейс фичи
    auth/
  shared/
    ui/           # Button, Modal, Input
    lib/          # утилиты, форматирование дат
    api/          # HTTP-клиент, базовая настройка
    config/

Если вы используете фреймворк вроде Next.js, папку app/ или pages/ задаёт его роутинг. Тогда держите в ней только маршруты и тонкие страницы, а логику — в features/ и shared/.

Правила, которые держат структуру в порядке

  • Зависимости идут в одну сторону: pages → features → shared. Модуль из shared не импортирует фичи.
  • Фичи не лезут друг в друга напрямую. Если orders нужен код из cart, импортируйте через features/cart/index.ts, а не из внутренних файлов.
  • Код живёт рядом с местом использования. Хук, нужный одному компоненту, лежит рядом с ним. В shared переносите только то, что реально используется в нескольких местах.
  • Неглубокая вложенность. Больше трёх-четырёх уровней папок обычно означает, что структура переусложнена.

Соглашения об именах

  • Компоненты — PascalCase: ProductCard.tsx. Одна папка на компонент, если у него есть стили, тесты и подкомпоненты.
  • Хуки — с префиксом use: useCart.ts.
  • Утилиты и прочие модули — camelCase или kebab-case; выберите один стиль и закрепите его в линтере.
  • Тесты — рядом с файлом: ProductCard.test.tsx.
  • Алиасы импорта вроде @/shared/ui вместо ../../../shared/ui.

Общий UI

shared/ui — это кирпичики интерфейса без бизнес-логики: кнопки, поля, модальные окна, типографика. Они не знают о корзине или заказах и получают всё через пропсы. Компонент, который знает о предметной области (например, CartItem), относится к фиче.

Где держать API-логику

Не вызывайте fetch прямо в компонентах. Удобная схема из трёх слоёв:

  1. shared/api — настроенный HTTP-клиент: базовый URL, заголовки, обработка ошибок.
  2. features/*/api.ts — функции запросов фичи: getCart(), addToCart().
  3. Хуки фичи — оборачивают запросы, например через TanStack Query, и отдают компонентам данные и статусы.

Так компонент отвечает только за отображение, а смена API затрагивает один слой.

Типичные ошибки

  • Папка utils/ или helpers/, куда складывают всё подряд.
  • Преждевременное дробление: десять папок для проекта из пяти компонентов.
  • Циклические импорты между фичами.
  • Разные соглашения в разных частях проекта без записанных правил.

Частые вопросы

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

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.