[Bug]: Default values are not refreshing properly
hernandcb opened this issue · 5 comments
Which packages are impacted?
-
remix-validated-form
-
@remix-validated-form/with-zod
-
@remix-validated-form/with-yup
-
zod-form-data
What version of these packages are you using?
- "remix-validated-form": "^4.6.9",
- "@remix-validated-form/with-zod": "^2.0.5",
- "zod-form-data": "^2.0.0"
Please provide a link to a minimal reproduction of the issue.
Steps to Reproduce the Bug or Issue
select "first" -> the values are loaded but the select does not change.
select "third" -> the select value is updated to "first"
select "second" -> all inputs are updated with the "third" values
Expected behavior
As a user I expect the values received are set as default values correctly. However, when reloading the page the values shown are those from previous requests, not the latest one.
Screenshots or Videos
No response
Platform
- OS: [Linux]
- Browser: [Chrome]
- Version: [114]
Additional context
First of all, thank for the great work with the library !
I'm using remix-validated-form to manage my form containing several input fields.
According to the change event on one select field I reload the route to get the values to fill in the form, which I pass as default values. However, the form is not setting those values properly.
Each time the route reloads the default values are those from the previous request, not the latest one. When I tested it using remix Form it works as expected.
You can also test how I expect it to work using the remix Form (there is a link below the form in the sandbox)
Is there something I'm not doing properly or it may be an issue with the library ?
Thanks for the detailed reproduction! It looks like the observed behavior is a combination of a couple different issues.
getInputProps
isn't setting the defaultValue of aselect
at all.
This will take some debugging to figure out, but it's definitely a problem.
- Usage of
useField
is preventing the form values from fully switching over.
It seems like having useField
in the page component is causing the form values to linger somehow, even after the form itself is reset. You can work around this by changing the id of the form every time you change the key.
This comes back to a pattern I keep seeing that I don't love, and that's using the "use outside forms" feature to use hooks in the component that renders the form. This inherently results in weird double updates because the ValidatedForm
itself creates the form store. This is kinda my fault because it looks like that doc actually does this to demonstrate the functionality. The original intent of this feature was to support the fact that HTML forms allow inputs to be outside the form element itself, but has kind of evolved into a common pattern.
Hi!
I believe I am experiencing the same issue, or at least it feels very related to this one.
However, I am not using useField
within the page component, but I made a separate input component in which I use the hook.
I have created my own codesandbox with a minimal example that matches my actual use case: https://codesandbox.io/p/sandbox/laughing-https-x47vkt?file=%2Fpackage.json%3A1%2C1
What it should be doing is managing a list of random numbers and persisting them on the filesystem. The only operations are add and remove. The loader will load the file and pass the content as default values to the form. Form submission will serialize the list to be written to the same file.
Steps to reproduce:
1.) Click "Add item". Each time a new number is added to a staged list and displayed as a checkbox that is checked.
2.) Click "save" to submit. The staged items are cleared and stored on the filesystem.
Expected behaviour: The added items should appear as checked checkboxes above the separator.
Actual behaviour: The newly added items render as an unchecked checkbox, making an immediate resubmission of the form remove them from the stored list.
The other way around also is buggy:
1.) In a list of at least 2 items, uncheck the first one
2.) Click "save" to submit.
Expected behaviour: the removed item should not be rendered again and the other items should be checked checkboxes.
Actual behaviour: the removed items are not rendered again, but state is keeping unchecked checkboxes at the same position, just now with other values from the list. Again, immediate resubmission will unwantedly remove them from the list.
I was trying to track the issue down in the code for a while, until I found an internal context object in useField
. Inspecting its value showed that it's actually stale and does not contain the new state. This then helped me find this on SO which I believe must be the reason it does not work: https://stackoverflow.com/questions/76426011/reload-data-in-form-after-submission-using-remix.
After first being a bit confused what you man with updating an some ID, I found that the recommended solution is updating the key
prop of the ValidatedForm
, and it does actually seem to be working.
If I understand it correctly that seems to be the way React works, and I am now unsure if there is anything remix-validated-form can do about it besides maybe mentioning it in the docs?
I hope this may help a bit. Big thanks for the great work on this library also from my side!
Not sure this has anything to do with the "use outside forms" pattern. I ran into the same issue just using this library exactly as described in the integrate-your-components section of the docs. Tried the suggestions of using resource-unique keys for the key
and id
form props, but even that fix was incomplete- while this caused it to reflect the correct data while navigating within the app, refreshing the page would always show the previous resource's data, somewhat bizarrely even if the correct data was being shown right before refreshing. Something is wrong with the way defaultValue is set.
Deepest apologies, MINUTES after posting this I discovered the issue, not directly related to remix-validated-form
. For anyone running into similar problems, what you may actually be running into is browser autocomplete behavior overriding the default value immediately after the correct value is filled in! autocomplete=off
on the form solved this issue in my case.