Replies: 2 comments
|
Your observation about how The Underlying Subscription ModelReact Hook Form decouples form state from React's component tree by maintaining values in an external store and notifying subscribers via an internal Subject/Observer event bus ( When a component subscribes via If you have a nested dictionary structure like: type FormValues = {
items: Record<string, { title: string; completed: boolean }>
}Updating
This prefix behavior is designed to make parent summary components automatically re-render when any child field updates (e.g. updating an array item updating a form-level validation or total). But in a dictionary of independent entities ( Using
|
| Mode | Behavior | Best Used For |
|---|---|---|
exact: false (Default) |
Matches on field path and any child/parent prefix mutations | Form sections, summary displays, array lengths |
exact: true |
Re-renders only when that precise path is modified | Large entity dictionaries, table cell inputs, isolated field controllers |
|
The current v7 docs now cover this explicitly. One detail worth correcting in the reply above: in 7.91.0, Also, since 7.81.0, That second case matters when a controller represents an entire object but another input edits one of its children. If that controller should update for child edits, use useController({ control, name: `items.${id}`, exact: false });The matching implementation makes the distinction explicit. These are subscription rules; they don't prevent renders caused by the surrounding React tree. I checked the examples with real hooks on RHF 7.91.0 / React 19.3.1: the object controller kept its old rendered value after a child update with the default option, updated with AI-assisted; those hook cases were run locally. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I guess I'm running into a more unique use case where I'm editing items in an object (keyed by id), rather than an array, this is so I can decouple what a form item is from the actual UI. (so useFieldArray isn't there to help/save me, though there are use-cases that
useFieldArraymay not work with either.Anyways, it's just today I realized a big part why Controllers might not play nice in setups that have nesting or parent/child editing is that Controller actually reads updates a lot more like an event bus it seems by default. It seems like this was the only behavior until very recently. This was pretty surprising since my understanding was
Controllerwas to adapt to a controlled component in React. Did not realize for an (admittedly neat) optimization that this was actually not true and it was not correct to assume Controlled aligned with how React works.I think the
exactprop/arg deserved a big mention in the docs, but honestly even before this prop being exposed, it would've been extremely helpful & useful to know this. Anyways, I'm lucky and appreciate having this functionality now, but this would really benefit from being a clear concept to anyone using the library rather than a rabbit hole. It's also a neat thing to know bc without knowing this is how Controller's work, I would've never fully realized it's a nice little optimization than can help with some watches where you want to reduce the subscription down to the specific path/event vs an equality check.All reactions