Какие инструменты используются для сложных форм с зависимыми полями в React?
Что проверяют
Умеете ли вы строить форму, где одно поле влияет на видимость, значения и валидацию других, и не утопить её в лишних ререндерах. Следом почти всегда просят объяснить, куда девается значение скрытого поля и где живёт правило зависимости: в разметке или в схеме.
Как отвечать
Начните с разделения ролей: состояние держит библиотека форм, правила валидации описывает схема, а зависимости выражаются через подписку на значения.
- React Hook Form: неуправляемые поля через
register, поэтому ввод не перерисовывает всю форму. Для зависимостей естьwatchиuseWatch(второй изолирует ререндер в одном компоненте),setValueиresetFieldдля подстановки и сброса,shouldUnregister, чтобы значения скрытых полей не уходили на сервер,useFieldArrayдля динамических списков; - Zod или Yup через
@hookform/resolvers: правило живёт в схеме, а не в JSX. В Yup это.when('fieldA', { is: ..., then: (s) => s.required() }), в Zod удобныz.discriminatedUnionдля веток формы иsuperRefineдля перекрёстных проверок; - Formik: знать стоит, в старых проектах он встречается часто, но на больших формах перерисовывает больше и обновляется редко;
- TanStack Form и формы UI-китов: у antd, например,
FormумеетdependenciesиForm.useWatch.
Покажите приём: производное значение считается прямо в рендере или в обработчике onChange первого поля, а не через useEffect с setValue. Эффект даёт лишний проход рендера и на мгновение показывает старое значение.
Где спотыкаются
Копируют старый синтаксис Yup, где в then передаётся готовая схема. В Yup 1.x там ожидается функция, и такая схема падает на первой же валидации.
Прячут поле условным рендером и забывают про его значение: без shouldUnregister или ручного resetField в отправку уходит то, что пользователь ввёл до переключения.
Выносят состояние формы в Redux «на всякий случай». Для зависимостей внутри одной формы это лишний слой, глобальный стор нужен, только если данные формы читают другие экраны.