Содержание
Коротко
На Dev.to описан подход к сложным формам на React: зависимости полей описывают в конфигурации, а не в цепочках useEffect.
Поля «подписываются» друг на друга (паттерн «наблюдатель»). MobX даёт мелкозернистую реактивность — перерисовывается только то, что реально изменилось.
Прототип фармацевтической формы с десятками полей заметно упростил код. Правила стали читаемыми даже для коллег вне клиентской части.
Что произошло
В корпоративных приложениях формы редко бывают «тремя полями ввода»: регистрация, оформление заказа, опросы, ввод данных.
Типичная боль — зависимость полей: страна показывает штат, тип заявки сужает типы подачи, комбинации значений включают проверки или предупреждения.
Стандартный путь в React — useEffect на каждое изменение. На пяти полях это ещё читается.
На тридцати с перекрёстными цепочками получается спагетти: бесконечные циклы, хрупкие тесты, страх добавить ещё одно правило.
Любое новое поле заставляет заново прослеживать граф эффектов, чтобы не сломать уже работающие цепочки.
Автор вспоминает старый XML-каркас интерфейса, где зависимость писали декларативно (dependsOn, loadFrom, clearOnChange) без ручных обработчиков.
Современный React декларирует разметку, но логику связей полей чаще пишут императивно. Альтернатива в статье — массив модели формы.
У поля явно указаны subscribesTo / subscribesOn, откуда грузить варианты (loadDataFrom) и когда показывать (visibleWhen). Читаешь сверху вниз — видишь контракт формы.
Для команды это ещё и способ обсуждать бизнес-правила на одном языке с серверной стороной.
Чтобы это работало, нужен механизм «поле A изменилось → заинтересованные поля узнали». Наивный обход всех полей после каждого нажатия клавиши на 30+ полях тормозит.
Решение — паттерн «наблюдатель» плюс хранилище с мелкозернистой реактивностью. Автор сравнивает Redux/Zustand с MobX и собирает функциональные хранилища без классов.
Движок подписок обрабатывает цепочки, циклы и гонки при параллельной загрузке — как раз те места, где императивные эффекты обычно и ломаются.
Автор честно пишет, что отладка движка сложнее, чем трассировка одного явного useEffect. Зато контракт формы перестаёт быть размазанным по компонентам.
Почему это важно
Сложные формы — не ниша фармы. Те же паттерны в финансовых сервисах, госуслугах, интернет-торговле и внутренних панелях.
Императивные эффекты плохо масштабируются как документация. Разработчик серверной части не «прочитает» бизнес-правила из десятка useEffect.
Конфиг как данные проще рецензировать, переносить между режимами просмотр/редактирование и частично генерировать с сервера.
Когда правила живут в данных, их проще версионировать вместе с API и покрывать тестами без монтирования всего дерева компонентов.
Есть и цена: свой формат конфигурации, кривая обучения, сложнее отладка движка подписок. Часть правил всё равно уйдёт в императивный код.
Для простой формы с одной зависимостью «страна → город» накладные расходы библиотеки не окупятся. Подход окупается на больших формах с повторяющимися цепочками.
| Подход | Как описаны связи | Типичный риск |
|---|---|---|
Цепочки useEffect |
В коде эффектов | Скрытые циклы, хрупкие правки |
| Конфиг + подписки | В данных модели | Кривая обучения движку |
| Только библиотека значений | Частично в коде | Связи всё равно вручную |
На практике
Если форма уже разрослась до «эффектов, которые дергают эффекты», сначала опишите зависимости на бумаге.
Часто выясняется, что половина правил — это две повторяющиеся операции: показать поле и обновить список вариантов.
Имеет смысл сначала описать эти два действия в конфиге, а уже потом решать, нужна ли отдельная библиотека или достаточно тонкого слоя поверх текущих форм.
- Выпишите граф: какое поле на что влияет (видимость, перезагрузка списка, сброс значения, правило проверки).
- Выделите два частых действия: показать/скрыть и обновить данные зависимого списка.
- Для больших форм оцените мелкозернистую реактивность (
MobXили аналог). - Тестируйте правила подписок как чистые данные — отдельно от монтирования компонентов React.
- Не отбрасывайте
Formik/React Hook Form: они хорошо держат значения и отправку; декларативные зависимости — про связи.
Отдельно решите, где живёт источник правды: только в клиентском конфиге или его можно частично отдавать с API. Второй вариант сильнее окупается, если форм много и они похожи.
Если команда уже сидит на Formik или React Hook Form, не выкидывайте их ради «чистоты» — добавьте слой зависимостей поверх, а не вместо.
Итог
Декларативные зависимости полей не отменяют useEffect навсегда.
Они переносят «кто на кого влияет» из императивного шума в читаемый конфиг. На прототипе фармацевтической формы это сократило объём логики и сделало правила понятнее команде.
Берите паттерн там, где сложность уже болит, а не как моду на каждый экран входа.
Если форма ещё простая — оставьте явные эффекты. Если граф зависимостей уже не помещается в голове одного разработчика, конфиг и подписки окупаются быстрее, чем ещё один слой useEffect.

