Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: useWatch return latest form value instead of the default value #2739

Closed
imcyee opened this issue Aug 27, 2020 · 15 comments · Fixed by #3505
Closed

Feature Request: useWatch return latest form value instead of the default value #2739

imcyee opened this issue Aug 27, 2020 · 15 comments · Fixed by #3505

Comments

@imcyee
Copy link

imcyee commented Aug 27, 2020

Is your feature request related to a problem? Please describe.
If the component with useWatch is unmounted and remount, the form value displayed default value instead of latest form value. Example use case: a long form, user can toggle to peak on the form summary and close it, but the value will be the initial default values.

Describe the solution you'd like
Returning latest form value whenever useWatch is mounted instead of default value

Issue related to this:
#2738

@imcyee imcyee changed the title useWatch returning latest form value instead of the default value Feature Request: useWatch return latest form value instead of the default value Aug 27, 2020
@bluebill1049 bluebill1049 added feature request request a feature to be added waiting-up-vote Waiting for votes from the community. labels Aug 27, 2020
@bluebill1049 bluebill1049 added this to Pending Feature Requests in React Hook Form Aug 27, 2020
@bluebill1049
Copy link
Member

Thanks for the feature request, it's been updated to the board.

@bluebill1049
Copy link
Member

bluebill1049 commented Sep 1, 2020

hey @cYee992 think twice, i think you can achieve this problem by the following:

useWatch({
  name: 'test',
  defaultValue: getValues().test
})

@bluebill1049 bluebill1049 removed feature request request a feature to be added waiting-up-vote Waiting for votes from the community. labels Sep 1, 2020
@bluebill1049 bluebill1049 moved this from Pending Feature Requests to Done in React Hook Form Sep 1, 2020
@imcyee
Copy link
Author

imcyee commented Sep 7, 2020

Thanks for the that. I just saw your comment in the midst of submitting a pull request... missed your comment.
But I have delved in the codebase a bit was thinking is it possible to let internal fieldsRef take priority if it exists, before default value.

In this line

const [value, setValue] = React.useState<unknown>(

Changed to this

In useWatch

const [value, setValue] = React.useState<unknown>(
   isUndefined(defaultValue)
     ? isString(name)
       ? isUndefined(getFieldValue(fieldsRef, name))
         ? get(defaultValuesRef.current, name)
         : getFieldValue(fieldsRef, name)
       : isArray(name)
         ? name.reduce(
           (previous, inputName) => ({
             ...previous,
             [inputName]: isUndefined(getFieldValue(fieldsRef, inputName))
               ? get(defaultValuesRef.current, inputName)
               : getFieldValue(fieldsRef, inputName)
           }),
           {},
         )
         : isUndefined(getFieldsValues(fieldsRef))
           ? defaultValuesRef.current
           : getFieldsValues(fieldsRef)
     : defaultValue,
 );

@bluebill1049
Copy link
Member

Thanks for the that. I just saw your comment in the midst of submitting a pull request... missed your comment.
But I have delved in the codebase a bit was thinking is it possible to let internal fieldsRef take priority if it exists, before default value.

In this line

const [value, setValue] = React.useState<unknown>(

Changed to this

In useWatch

const [value, setValue] = React.useState<unknown>(
   isUndefined(defaultValue)
     ? isString(name)
       ? isUndefined(getFieldValue(fieldsRef, name))
         ? get(defaultValuesRef.current, name)
         : getFieldValue(fieldsRef, name)
       : isArray(name)
         ? name.reduce(
           (previous, inputName) => ({
             ...previous,
             [inputName]: isUndefined(getFieldValue(fieldsRef, inputName))
               ? get(defaultValuesRef.current, inputName)
               : getFieldValue(fieldsRef, inputName)
           }),
           {},
         )
         : isUndefined(getFieldsValues(fieldsRef))
           ? defaultValuesRef.current
           : getFieldsValues(fieldsRef)
     : defaultValue,
 );

Yea it's possible. what's the usage like? cause it's pretty easier to provide a defaultValue at useWatch as well, save that nested logic inside useWatch

useWatch({
  defaultVlaue: getValues('yourInput')
})

@imcyee
Copy link
Author

imcyee commented Sep 8, 2020

Yup, it is really easy to provide the default value, just that it feels weird whenever you unmount and remount the data display component, value goes back to initial.

Could be some gotcha moment.

The usage will be whenever you are unmounting and remounting the component, the value will be the latest fieldRef value:
Potential usecase for:-
*) modal with useWatch
*) Form with shouldUnregister:false still able to get back the latest value even the input component is unmounted
*) mounting and unmounting a component for data display
-) Mostly involve mounting and unmounting it.

  • All usecases above still can be solved by your solution. Just feels that why fieldRef value does not take precedence over default value when first mounted.

@bluebill1049
Copy link
Member

valid case @cYee992 thanks for the detail. This may be a breaking change to existing users with watch/useWatch as right now it's fall back to default values or defaultValue, but it's worth considering this change and I agree with your opinion above. 👍

@imcyee
Copy link
Author

imcyee commented Sep 8, 2020

I found that watch API actually has the precidence where fieldRef value > default value.

return assignWatchFields<TFieldValues>(

if (isString(fieldNames)) {
        return assignWatchFields<TFieldValues>(
          fieldValues,
          fieldNames,
          watchFields,
          isUndefined(defaultValue)
            ? get(combinedDefaultValues, fieldNames)
            : (defaultValue as UnpackNestedValue<DeepPartial<TFieldValues>>),
          true,
        );
}

return isUndefined(value)

 return isUndefined(value)
    ? isSingleField
      ? inputValue
      : get(inputValue, fieldName)
    : value;

@bluebill1049
Copy link
Member

bluebill1049 commented Sep 8, 2020

also, be mindful that be default, react hook form unregister input after they get unmounted, so even this feature going through it will only applicable for shouldUnregsiter: false.

for shouldUnregister: true by default: https://codesandbox.io/s/hungry-waterfall-kyp4s

@imcyee
Copy link
Author

imcyee commented Sep 8, 2020

also, be mindful that be default, react hook form unregister input after they get unmounted, so even this feature going through it will only applicable for shouldUnregsiter: false.

Yup. Correct. The field will be erased if the main input got erased. but as long as the field input still there, eg: modal and re-mounting the data display component still able to get back the fieldRef value.

@bluebill1049
Copy link
Member

also, be mindful that be default, react hook form unregister input after they get unmounted, so even this feature going through it will only applicable for shouldUnregsiter: false.

Yup. Correct. The field will be erased if the main input got erased. but as long as the field input still there, eg: modal and re-mounting the data display component still able to get back the fieldRef value.

Yes, personally I am lean towards not include that extra logic into watch/useWatch (keep it simple), but I do agree with your point of view as well, it's convenient without having to do the getValues() part when your watching value gets unmounted and mounted, and I am open for everyone's request if quite a lot of developers required such feature/correction, I am more than happy to include the amendment. let's give it sometimes, and it's on the feature request board.

@imcyee
Copy link
Author

imcyee commented Sep 8, 2020

Alright. Thanks for your time.

@bluebill1049 bluebill1049 moved this from Done to Pending Feature Requests in React Hook Form Sep 8, 2020
@bluebill1049
Copy link
Member

Sorry, i am moving it back to request feature board.

@bluebill1049 bluebill1049 added feature request request a feature to be added waiting-up-vote Waiting for votes from the community. labels Sep 8, 2020
@imcyee
Copy link
Author

imcyee commented Sep 8, 2020

Thank you!

@bluebill1049
Copy link
Member

This is getting fixed in the next release.

@bluebill1049 bluebill1049 removed feature request request a feature to be added waiting-up-vote Waiting for votes from the community. labels Nov 25, 2020
@bluebill1049 bluebill1049 moved this from Pending Feature Requests to In progress in React Hook Form Nov 25, 2020
@bluebill1049 bluebill1049 added the feature request request a feature to be added label Nov 27, 2020
@bluebill1049 bluebill1049 moved this from In progress to Done in React Hook Form Nov 28, 2020
@bluebill1049 bluebill1049 removed the feature request request a feature to be added label Dec 11, 2020
@marcospassos
Copy link

marcospassos commented May 31, 2022

I can confirm this issue is still present in the latest version. @bluebill1049 is it a regression?

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 10, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
Development

Successfully merging a pull request may close this issue.

3 participants