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

[Bug]: Default values are not refreshing properly #315

Open
2 of 4 tasks
hernandcb opened this issue Aug 9, 2023 · 4 comments
Open
2 of 4 tasks

[Bug]: Default values are not refreshing properly #315

hernandcb opened this issue Aug 9, 2023 · 4 comments
Labels
bug Something isn't working

Comments

@hernandcb
Copy link

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.

https://codesandbox.io/p/sandbox/validated-form-default-values-kjn5xk?file=%2Fapp%2Froutes%2Findex.tsx

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 ?

@hernandcb hernandcb added the bug Something isn't working label Aug 9, 2023
@airjp73
Copy link
Owner

airjp73 commented Aug 11, 2023

Thanks for the detailed reproduction! It looks like the observed behavior is a combination of a couple different issues.

  1. getInputProps isn't setting the defaultValue of a select at all.

This will take some debugging to figure out, but it's definitely a problem.

  1. 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.

@nimajneb
Copy link

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!

@cxreiff
Copy link

cxreiff commented Jan 6, 2024

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.

@cxreiff
Copy link

cxreiff commented Jan 6, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants