Ешьте React-компоненты по кусочкам

пт, 6 июня 2025 г. - 2 мин чтения
Компоненты React, разделённые на модули

🥕 Ешьте React-компоненты по кусочкам

На одном проекте у нас был разработчик, который упаковывал всё в один файл. Слайдер? Там же стрелки, индикаторы, логика автопрокрутки и дата-фетч. Попап? Значит, все хендлеры, модальные слои, порталы и валидация должны жить рядом. Файл разрастался до тысяч строк, ревью превращалось в пытку, а любой новый человек говорил: «Бипец, работать невозможно».

React позволяет держать всё в одном компоненте, но это не значит, что стоит так делать. Разбейте сложный UI на маленькие части — и вы вздохнёте свободно.


Почему монолитные компоненты вредят

🔍 Не видно намерений

Когда в компоненте десятки состояний, эффектов и колбэков, становится сложно понять, какая часть отвечает за что. Ревьюер пропускает важные детали, просто потому что глаза замылились.

🐛 Больше багов и регрессий

Одно изменение в глубине компонента легко ломает соседнюю логику. Нет изоляции — нет уверенности.

🧠 Высокий порог входа

Новому разработчику нужно изучить тысячу строк, чтобы поправить мелочь. Он не понимает, где заканчивается бизнес-логика и начинается рендер.


Как дробить огромный компонент

  1. Выделите зоны ответственности. Например, Slider, SliderArrow, SliderBullets, useSliderAutoplay, useSliderKeyboard.
  2. Создайте папку компонента. Внутри components/Slider заведите index.ts, Slider.tsx, SliderArrow.tsx, SliderBullets.tsx, hooks/useSliderAutoplay.ts.
  3. Перенесите логику в хуки. Состояние и побочные эффекты прячем в useSomething. UI оставляем чистым.
  4. Документируйте интерфейсы. Описывайте пропы и контракты, чтобы другие могли переиспользовать части без сюрпризов.
  5. Добавьте тесты на модули. Маленькие компоненты легче покрывать unit- и интеграционными тестами.

Пример структуры после рефакторинга

components/
  Slider/
    index.ts
    Slider.tsx
    SliderControls.tsx
    SliderDots.tsx
    hooks/
      useSliderAutoplay.ts
      useSliderNavigation.ts
    utils/
      getNextSlide.ts
      getPrevSlide.ts

index.ts экспортирует публичный интерфейс, а внутренние детали остаются спрятанными. Команда видит аккуратный API и не боится открыть папку.


Когда обязательно дробить

  • Компонент превышает 200–300 строк.
  • Внутри есть более трёх контекстов или слайсов состояния.
  • В jsx-дереве больше пяти уровней вложенности.
  • На один файл приходится несколько доменных задач (например, и оплата, и доставка, и подтверждение).
  • Ревьюеры регулярно пишут «сложно читать».

Итог

Большие компоненты тормозят развитие продукта. Как только видите «много всего в одном файле» — дробите: выносите UI в подкомпоненты, логику в хуки, а публичный интерфейс собирайте через index. Команда станет быстрее, ревью — приятнее, а поддержка перестанет быть болью.