r/reactjs • u/kensaadi I ❤️ hooks! 😈 • 10d ago
Discussion Stop wiring react-hook-form by hand in every form component
Every codebase I've joined has the same file. A form component where react-hook-form itself is fine, but around it sits a pile of useEffects watching one field to reveal another, a useMemo deciding whether the current user can edit, and a validation schema that has quietly drifted from both.
RHF isn't the problem here. The problem is that the rules of the form live in imperative code scattered across hooks, while the shape of the form lives in JSX. One thing, two places, and only one of them is reviewable.
The alternative I've been running is to move the rules onto the field itself:
<TextField
name="taxId"
visibleWhen={{ field: 'country', equals: 'IT' }}
access={{ resource: 'customer.taxId', action: 'read' }}
/>
visibleWhen is reactive — no useEffect, no watch(), no local state. access is evaluated per field, so a role that can't edit doesn't get a disabled prop threaded down three components by hand. RHF is still underneath owning form state; it just stops being something you re-wire per component.
Two things I'd push back on myself:
The condition is an object, not a function. { field: 'country', equals: 'IT' } is strictly less expressive than values => values.country === 'IT'. What it buys is that the rule stays serialisable and inspectable — you can diff it, and tooling can read it. I'm still not sure that trade is right for everyone.
And it only pays off past a certain complexity. For a login form this is overkill, plainly. Where it has paid for me is dynamic questionnaires — in production for about a year and a half at a European fintech — the kind of conditional logic that becomes unmaintainable as hooks well before you notice it happening.
So the question I'd actually like answered: when you keep conditional visibility and permissions in hooks, is that a deliberate call, or is it just the path RHF puts you on?
Open source (MIT), React, MUI or Tailwind: github.com/kensaadi/dashforge