`useWatch` doesn't react to value changes caused by a `defaultValue` being set via `useController(...)`
See original GitHub issueDescribe the bug
useWatch doesn’t react to value changes caused by a defaultValue being set via useController(...)/register(...)
To Reproduce Steps to reproduce the behavior:
- Go to https://codesandbox.io/s/xenodochial-forest-tez5p?file=/src/App.tsx
<WatchingCustomInput>will render in the page, setting up anuseWatch({ control, name: "myInput" })which correctly returnsundefined, since no “myInput” has been registered in the page<CustomInput>then gets rendered, which sets up auseController(name: "myInput", defaultValue: "myDefaultValue")which correctly sets the value formyInputto"myDefaultValue"
Expected behavior
At this point, I would expect <WatchingCustomInput> to re-render, since myInput changed from undefined to "myDefaultValue", but that doesn’t happen.
Codesandbox link (Required)
- https://codesandbox.io/s/xenodochial-forest-tez5p?file=/src/App.tsx
- here’s a similar example using
watch()instead, the results are the same
Desktop:
- OS: macOS
- Browser: chrome
- Version: 91.0.4472.114
Additional context While the example itself might make little sense, I’ve synthesised it from a much more complex form that involves components reacting to values set by other components.
In my own code, defaultValue is a bit unpredictable, which is the reason why I choose to populate it via useController rather than supplying it directly to the useForm.
I’m using useWatch from another component assuming it always returns the current value for the watched field.
If anybody has suggestions or needs more examples from my end, just let me know.
Thanks! 😊
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (3 by maintainers)
Top Related StackOverflow Question
Can you post this in the Github discussion? i will have a look at it tmr.
@bluebill1049 Thank you so much for the replies.
I’ve been trying to implement this solution by removing the
defaultValuefrom theuseController(...), and setting it using auseEffectwhen the component is rendered. Something like this:However, while the value for
hasUserAcceptedPrivacyPolicyis effectively set totrue, theuseWatchwon’t trigger. Therefore,<UserEmail>won’t display an input.https://codesandbox.io/s/wizardly-pasteur-rq8z1?file=/src/App.tsx
Hacky workaround
I noticed that letting the
useEffectrun twice, makes things work. I’m assuming that it’s just a coincidence, probably something related towatchbeginning to subscribe to changes only after a some other event.https://codesandbox.io/s/clever-hooks-whzud?file=/src/App.tsx
Another terrible hack would be using a
setTimeoutor some sort of emptyasync/await, to delay the run of the firstuseEffect. This again makes me think that I’m calling thesetValueway before RHF has started watching for value changes to notify viawatch.This of course doesn’t look like something sane to do 😰.
https://codesandbox.io/s/brave-margulis-70ic1?file=/src/App.tsx
Am I doing something wrong here?