useStore causing weird behavior to form.reset()
reproduction: https://github.com/mamlzy/tanstack-form-repro
GitHub
GitHub - mamlzy/tanstack-form-repro
Contribute to mamlzy/tanstack-form-repro development by creating an account on GitHub.
28 Replies
fair-rose•4w ago
This likely is because the rerender adds another check of
useAppForm's defaultValues against the form reset's defaultValues.
Does the error persist if you add a { keepDefaultValues: true } as second argument to the reset?unwilling-turquoiseOP•4w ago
Adding
{ keepDefaultValues: true } only works in handleSet. The bug still occurs in handleReset, it doesn’t reset to the latest defaultValues, which contain 2 dummy persons.unwilling-turquoiseOP•4w ago
fair-rose•4w ago
where are your
defaultValues coming from?unwilling-turquoiseOP•4w ago
defaultValues coming from formOpts in shared.ts
fair-rose•4w ago
The main source of the problem is our async
defaultValues support. You can write async data like this, for example:
and it'll update when the new data is ready.
The problem is that form.reset might happen right after a call to the backend, so in the small window where async data isn't there yet but the form was reset, it would fall back to emptyData. The passed value to form.reset was originally intended to hide that flickering.
You noticed yourself that it becomes problematic though. With the useStore, it triggers a new update, and the form sees:
So it overrides them, thinking it's async data coming in. keepDefaultValues would force the reset's provided value to be considered the source of truth.
But that becomes a problem again when you pass it undefined, as you sawunwilling-turquoiseOP•4w ago
So this is a bug that needs to be fixed on the library side, not on my side, am i right?
fair-rose•4w ago
I doubt there's a solution that makes everyone happy, but yes it's something we need to address
that aside, why are you using
reset to set data like this?
just for demonstration purposes?unwilling-turquoiseOP•4w ago
no, i actually use it for my project
fair-rose•4w ago
why manage it through a reset? What data are you assigning this way?
unwilling-turquoiseOP•4w ago
the
reset feature works fine in react-hook-form, but not in this library. I actually prefer this library, but I ran into this bug.unwilling-turquoiseOP•4w ago
This is the project I’m currently working on.
fair-rose•4w ago
yeah, because RHF manages async default values differently.
So in your case, you have a search element, and when it finds something, it populates a form with the order's data?
unwilling-turquoiseOP•4w ago
Right now, the search only retrieves items and isn’t related to data ordering. I just want to reset the forms to the new
defaultValues, but doing so makes the items disappear.fair-rose•4w ago
if you consistently change
defaultValues, having them in state is the safer approach.
setDefaultValues and then any form.reset will fall back to the latest state of defaultValues
the temporary data of form.reset(data) (even without the bug) is not a good fitunwilling-turquoiseOP•4w ago
how about this, is it ok?
Do I need to make any adjustments? The “Reset All” button already works as expected, though.
fair-rose•4w ago
Looks fine. I assume the
setInboundsDefaultValues is part of a function and not called on every render.
The part that I suggested would look like this:
that way, you keep track for subsequent resets (and still allow async initial values which keepDefaultValues would block)unwilling-turquoiseOP•4w ago
Thank you Luca for helping me! please let me know once this bug is fixed.😁
fair-rose•4w ago
will do! It's a tough one to crack internally, so this can take a while
unwilling-turquoiseOP•4w ago
anyway, i'm not be able to do that if i'm using
withForm() right?fair-rose•4w ago
Why not? withForm is a HOC so that the form prop it accepts is properly typed
unwilling-turquoiseOP•4w ago
right now the
defautValues is in shared.ts, shared for parent (useForm) and child (withForm) component, how do i put useState value in defaultValues?
fair-rose•4w ago
with the spread, you can overwrite it in your form hook:
unwilling-turquoiseOP•4w ago
so how it look like in
withForm() component?fair-rose•4w ago
withForm is a HOC, so at runtime, the defaultValues you passed it no longer exist
they serve to type your form prop, not to be actual values to use
withFieldGroup does need them at runtime, but only to know what Object.keys it needs to map. The values of it are irrelevantunwilling-turquoiseOP•4w ago
i think i get it now. thank you 🙂
fair-rose•4w ago
If it makes it clearer. With all the details taken away,
withForm is this:
unwilling-turquoiseOP•4w ago
working as expected, thanks again Luca!
now i just call
form.reset() without passing any arguments