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

issue: Incorrect getValues() after reset when isValid is destructured from formState #11368

Closed
1 task done
IanVS opened this issue Jan 8, 2024 · 12 comments
Closed
1 task done
Labels
improve documentation documentation update required

Comments

@IanVS
Copy link
Contributor

IanVS commented Jan 8, 2024

Version Number

7.49.2

Codesandbox/Expo snack

https://codesandbox.io/p/sandbox/funny-kapitsa-j7vqmk

Steps to reproduce

  1. Go to reproduction
  2. Add a new tag with the button, or remove the existing tag
  3. Click the "reset" button
  4. Notice that getValues() is different from what is rendered.

Expected behaviour

I was confused why getValues() was returning something different from what the form was actually rendering, and narrowed it down to only happening when isValid is destructured from formState. I need to use reset with keepDirtyValues, and it almost works, except for resetting the value returned by getValues()

What browsers are you seeing the problem on?

No response

Relevant log output

No response

Code of Conduct

  • I agree to follow this project's Code of Conduct
@Moshyfawn
Copy link
Member

The difference between watch and getValues is that getValues will not trigger re-renders or subscribe to input changes.

getValues isn't designed to be called on render, as it's just a getter as opposed to a React value subscriber.

@Moshyfawn
Copy link
Member

Consider using useWatch / watch to subscribe your UI to field value updates.

@IanVS
Copy link
Contributor Author

IanVS commented Jan 8, 2024

I don't really want to subscribe to the updates, though, I just want to have access to the latest values when render does happen to be called.

@IanVS
Copy link
Contributor Author

IanVS commented Jan 8, 2024

And render is being called in this case, but getValues() is returning the incorrect value. You can see that it works fine if isValid is commented out.

@IanVS
Copy link
Contributor Author

IanVS commented Jan 8, 2024

I just checked, and watch() returns the incorrect value as well.

@Moshyfawn Moshyfawn added the status: under investigation aware of this issue and pending for investigation label Jan 8, 2024
@Moshyfawn
Copy link
Member

Moshyfawn commented Jan 8, 2024

I understand this may be tedious, but could you please review this codesandbox to identify any differences in core logic between my implementation and yours?

This will help us determine the cause of the issue you are experiencing. Currently, my codesandbox is functioning as expected: the values displayed in the code element are not updated in real-time as the 'tags' field values change, as getValues does not create a subscription. However, switching back to watch does correctly synchronize the displayed values. Resetting the form values yields the correct result too.

@IanVS
Copy link
Contributor Author

IanVS commented Jan 8, 2024

Thanks so much for taking a look, @Moshyfawn. I've forked your sandbox to show the issue:

https://codesandbox.io/p/devbox/admiring-jasper-8fctzf

The difference is that I am using keepDirtyValues, not just keepDirty. So, after changing tags, the "reset" button should basically do nothing to the form or the values logged to the console (only updating default values), but the console log is incorrect in this fork. It is like it returns the default value, not the current value.

@bluebill1049
Copy link
Member

@IanVS i couldn't reproduce the issue (with your steps), could you share a video?

@Moshyfawn
Copy link
Member

@IanVS I couldn't reproduce the issue (with your steps), could you share a video?

The codesandbox that Ian linked to is my codesandbox that I've shared with them. I've modified it again to suit Ian's use-case; you can now reproduce the problem.

Here's the screencast too. Note that after the form is reset, there is a re-render that forces the values to be logged, but they don't update to the values in the form. The above tags list in the app never changes from default values.

I've tracked it down to how the values are composed, possibly due to how _state.mount is calculated, where _proxyFormState.isValid equals "all" and we never pass keepStateOptions.keepIsValid, so _state.mount is false, hence no update.

csb-rhf-dirty.mp4

@bluebill1049
Copy link
Member

bluebill1049 commented Jan 10, 2024

you can resolve this issue with the following, it does make things complicated when you try to provide reset values and then keep what on the screen.

reset(
  undefined,
  { keepDirty: true, keepDirtyValues: true },
)

I will add a note in the doc.

  • It's fine to run reset without argument as long as you have provided a defaultValues at useForm.
reset(); // update form back to default values

reset({ test: 'test' }); // update your defaultValues && form values

reset(undefined, { keepDirtyValues: true }); // reset other form state but keep defaultValues and form values

@bluebill1049 bluebill1049 added improve documentation documentation update required and removed status: under investigation aware of this issue and pending for investigation labels Jan 10, 2024
@IanVS
Copy link
Contributor Author

IanVS commented Jan 11, 2024

Thanks, but I do want to update the default values in my situation (and any non-dirty form values). Are you saying that this is working as intended?

@bluebill1049
Copy link
Member

bluebill1049 commented Jan 11, 2024

@IanVS is rather a difficult case when isValid is subscribed because it will need to trigger revalidation after mounted, and the getValues return value is base mounted. I will take a look at it again after work.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 11, 2024
rafaelcalhau pushed a commit to rafaelcalhau/react-hook-form that referenced this issue May 5, 2024
…es (react-hook-form#11384)

* fix react-hook-form#11368 keep form state mounted when keeping values

* fix logic condition

* update unit tests

* remove only

* improve unit test
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
improve documentation documentation update required
Projects
None yet
Development

No branches or pull requests

3 participants