react-hook-form: Can't seem to update a field when using useFieldArray with setValue
Please consider asking the question at our spectrum channel.
https://spectrum.chat/react-hook-form
Describe the question?
To Reproduce Steps to reproduce the behavior:
- use
useFieldArray - try to update a certain field in all members of the array using
setValue fieldsis out of sync withwatch
Detailed explanation:
I’m using useFieldArray to manage an array of objects.
One of the fields in these objects has to be set manually, since it affects the other array members (it’s a toggle of who’s the primary member of the array, toggling one as the primary toggles the others off)
Using setValue makes the fields object out of sync from what comes from watch.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 30 (13 by maintainers)
I have had a similar problem: I’m using useFieldArray and watch this fields with useWatch to have changes within the fields reflected directly. When I loaded existing values from the database and populated the form via setValue, this didn’t work with array fields. The values have been set via setValue(), but they were directly overwritten due to re-renders and inconsistencies between useFieldArray fields and useWatch.
I changed my code the following way and it works now:
<Controller>component for field array fields (because they are not registered yet). I had default values for these input and when they got mounted, they were overwriting the loaded value from the database.useFieldArrayanduseWatchto get a controlled field array. the returned fields fromuseFieldArrayshould be used as defaultValue for useWatch, e.g. `useWatch({ name: ‘parameters’ , defaultValue: fields})``reset({ ... })instead ofsetValue()I’m using
"react-hook-form": "^7.6.3".I have the same issue in nested field arrays. The top-level field array doesn’t work properly, but the second one is good with fields.
good question @Chandu here is what happened.
Because useFieldArray is relay on uncontrolled input as well (that’s why no re-render when the user is typing), so which means state lives inside inputs, this also means there are times when we need to reshuffle the inputs and potentially destroy the association between inputs, so the updated input values will be ready until the next render phase is complete, by supplied a default value with fields it close the gap with that single render.
@bluebill1049 Thanks. It worked.
@Chandu try to supply fields for the watch as default value
watch('xxx', fields')that should solve the problem.I see. Thanks for your replies!
setValue: only trigger re-render when an error occurred or disappearedwatch: re-render what’s watched.So if, for example, I want to render for each item if its
primaryor not, I can’t useitem.primarysince that doesn’t ever gets updated, I have to usewatch?