airjp73 / rvf

Easy form validation and state management for React and Remix
https://rvf-js.io
MIT License
827 stars 66 forks source link

[Bug]: Incorrect Form Validation Behavior #306

Closed 0xIndalamar closed 1 year ago

0xIndalamar commented 1 year ago

Which packages are impacted?

What version of these packages are you using?

"@remix-validated-form/with-zod": "^2.0.6", "remix-validated-form": "^5.0.2",

Please provide a link to a minimal reproduction of the issue.

https://codesandbox.io/p/sandbox/optimistic-dubinsky-j5sfr6?file=%2Fapp%2Froutes%2Findex.tsx%3A1%2C1-64%2C1

Steps to Reproduce the Bug or Issue

  1. Click «Next» on the first step
  2. Enter a value in the First name field
  3. By now you should have seen that the Last Name field was also validated.

Expected behavior

As a user, I expected the validation to occur only for the currently modified field, but I am seeing validation being triggered for the entire form.

Screenshots or Videos

No response

Platform

Additional context

No response

airjp73 commented 1 year ago

Hi!

Unfortunately, this looks like this is a bug with the wizard implementation, rather than this library.

The bug

Part of the observed behavior is caused by an intentional breaking change in v5. Here's the excerpt from the release notes:

## Validation behavior changed when validating one field

In order to improve the DX when using dependent validations, validating a single field now checks other fields in the form as well. The behavior for that is like this:

If another field no longer has an error, it will be cleared automatically.
If another field's error has changed, it will be updated automatically.
If another field has a new error, it will only add the error if the field has been touched or the form has already been submitted unsuccessfully.

That last point is key to understanding the issue in this reproduction. When you click Next, the ValidatedForm remembers that it has been submitted, and all validationBehaviors in the form will use the whenSubmitted variant.

You can see see this as well with the following reproduction:

The fix

In order to fix this, the form state needs to be reset in between wizard steps.

I'm sure there are several ways you can approach this, but the way I normally build wizards in remix is like this:

This approach has a couple benefits:

I'm sure its also possible to come up with a solution that works without submitting the form on each step, but the issue of resetting the "hasBeenSubmitted" state is something you'll want to keep in mind for it.