`useWatch` doesn't react to value changes caused by a `defaultValue` being set via `useController(...)`

See original GitHub issue

Describe 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:

  1. Go to https://codesandbox.io/s/xenodochial-forest-tez5p?file=/src/App.tsx
  2. <WatchingCustomInput> will render in the page, setting up an useWatch({ control, name: "myInput" }) which correctly returns undefined, since no “myInput” has been registered in the page
  3. <CustomInput> then gets rendered, which sets up a useController(name: "myInput", defaultValue: "myDefaultValue") which correctly sets the value for myInput to "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)

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:closed
  • Created 2 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
bluebill1049commented, Jul 22, 2021

Can you post this in the Github discussion? i will have a look at it tmr.

0reactions
giovannipillercommented, Jul 22, 2021

@bluebill1049 Thank you so much for the replies.

use setValue will trigger watch to update input change.

I’ve been trying to implement this solution by removing the defaultValue from the useController(...), and setting it using a useEffect when the component is rendered. Something like this:

const myOwnDefaultValue = true;
React.useEffect(() => {
  // checking for undefined, to simulate setting a default value
  if (field.value === undefined)
    setValue("hasUserAcceptedPrivacyPolicy", myOwnDefaultValue);
}, [field.value, setValue]);

However, while the value for hasUserAcceptedPrivacyPolicy is effectively set to true, the useWatch won’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 useEffect run twice, makes things work. I’m assuming that it’s just a coincidence, probably something related to watch beginning to subscribe to changes only after a some other event.

const myOwnDefaultValue = true;
React.useEffect(() => { 
 if (field.value === undefined || field.value === myOwnDefaultValue)
   setValue("hasUserAcceptedPrivacyPolicy", myOwnDefaultValue);
}, [field.value, setValue]);

https://codesandbox.io/s/clever-hooks-whzud?file=/src/App.tsx


Another terrible hack would be using a setTimeout or some sort of empty async/await, to delay the run of the first useEffect. This again makes me think that I’m calling the setValue way before RHF has started watching for value changes to notify via watch.

const myOwnDefaultValue = true;
React.useEffect(() => {
  setTimeout(() => {
    if (field.value === undefined)
      setValue("hasUserAcceptedPrivacyPolicy", myOwnDefaultValue);
  });
}, [field.value, setValue]);

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?

Read more comments on GitHub >

github_iconTop Results From Across the Web

watch values undefined when using defaultValue in Controller
I'm setting a defaultValue to a Controller but using watch still returns undefined in the first render. Is that correct? here's the sandbox....
Read more >
useWatch | React Hook Form - Simple React forms validation
It's optional if you are using FormContext. defaultValue, unknown. default value for useWatch to return before the initial render.
Read more >
React Hook Form useWatch not displaying correct value in ...
For anyone that may have this issue, I was able to fix it by using setValues to initially set the value on render...
Read more >
React Hook Form: A guide with examples - LogRocket Blog
Learn all about using forms in React with React Hook Form, including how to create and validate forms — even with third-party components....
Read more >
react-hook-form controlled input onblur doesn't work - You.com
Changing the valiation mode to onChange will validate after change event is triggered, when all of the values are up-to-date:.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found