Зміст
Коротко
На 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.

