final-form / react-final-form

🏁 High performance subscription-based form state management for React
https://final-form.org/react
MIT License
7.39k stars 481 forks source link

When Use SubmitError . Input Field is Invalid Forever. in 'React' Final Form #403

Open pagongamedev opened 5 years ago

pagongamedev commented 5 years ago

when i use <button type="submit" disabled={invalid}>

and use submitError

const onSubmit = async values => {
  if (values.username !== "erikras") {
    return { username: "Unknown username" };
  }

Meta in Username is set Invalid:true When OnChange Username Input it not change meta.invalid

submit button so can't click anymore.

// but i can hide submitError by meta.dirtySinceLastSubmit

 {(meta.error ||
                  (meta.submitError && !meta.dirtySinceLastSubmit)) &&
                  meta.touched && <span>{meta.error || meta.submitError}</span>}

Sandbox Link

https://codesandbox.io/s/m9vnk7kw8

piehouserat commented 5 years ago

I have the same issue, surely as soon as a field that was returned as a submit error has been touched it should not be invalid anymore. This issue prevents me from disabling the submit button if invalid :(

piehouserat commented 5 years ago

@erikras can we get some clarification on this, is this a bug or desired behaviour? If the latter, is there a suitable workaround?

kocur4d commented 5 years ago

Same here. I would expect the submitError to be cleared when field is touched. I am looking forward to find out if this is a bug or intended behaviour.

OR if the submitError needs to stay as it is the form shouldn't be considered invalid after the change of the value on the field submitError had happen.

sophielevens commented 5 years ago

Hey @erikras,

Thanks for your work on this plugin, I've loved working with it so far.

However, I am experiencing the same issue as @pagongamedev. @piehouserat and @kocur4d and wondered if this is a bug you might be looking into at some point in the future or if it isn't actually a bug.

Thanks! Sophie

More4ever commented 5 years ago

I'm using such construction for now

disabled={
              submitting
                // Check is form has submit errors and wasn't edited after submit
                || (!dirtySinceLastSubmit && hasSubmitErrors) 
                // Check if form has validation errors
                || Object.keys(errors).length 
                || pristine
                || validating
            }
valeryq commented 5 years ago

Same issue. Form has invalid=true always if exists submitError.

sfblaauw commented 5 years ago

+1

paulovitin commented 5 years ago

Guys, this works:

disabled={hasValidationErrors || (hasSubmitErrors && !dirtySinceLastSubmit)}
sfblaauw commented 5 years ago

@paulovitin 👏

cizz3007 commented 5 years ago

Same issue. Is there any way ? to initiate specific fields meta after get submitError?

TrejGun commented 5 years ago

same here, either need to remove keys from submitErrors and update hasSubmitErrors or add dirtyFieldsSinceLastSubmit so we can match it agains submitErrors

TrejGun commented 5 years ago

ok there is one solution

const form = useForm();
const isValid = valid || !(hasValidationErrors || hasSubmitErrors && !Object.keys(submitErrors).every(key => form.getFieldState(key).dirtySinceLastSubmit));

then

disabled={submitting || pristine || !isValid}
romanlex commented 5 years ago

same issue

zerubeus commented 5 years ago

+1

ignatevdev commented 5 years ago

Any news?

Stumbled upon this after migrating from redux-form to react-final-form.

Useful to mention that redux-form resets the submitErrors upon change and it solves this problem.

Is there any reason why final-form works differently?

ignatevdev commented 5 years ago

For anyone landing here, I have made a simple helper for clearing the errors after submit. https://github.com/ignatevdev/final-form-submit-errors

It basically listens for changes in your form and tries to detect if any of the errors in your submitErrors object corresponds to the changed field.

If it does - it clears the error and also removes the path of an error, if necessary, to avoid empty objects and arrays for deep fields.

The library is quite raw and not battle tested yet, but if anyone wants to try it out and give a feedback - you are welcome.

erikras commented 5 years ago

So the question is a debatable one: "When does a field with a submit error become valid?" This is specifically why the dirtySinceLastSubmit flag was added, to give everyone finer control over the issue. For example, perhaps the answer to "Should a field with a submit error ever be invalid at all?" might be "no". I don't think the answers are clearly black-and-white on either of these. And changing the behavior to have valid/invalid only depend on client-side validation would be a breaking change. Perhaps it would require a separate submitValid/submitInvalid pair for the most recent submit errors?

Also, this sort of hacking that @ignatevdev is exactly the sort of thing that the mutators system was built for.

wmertens commented 5 years ago

@pagongamedev so maybe this issue would be resolved for you if this was documented in some different way?

erikras commented 5 years ago

I would also recommend against disabling your submit button while invalid. The primary reason for this is that Final Form will mark all your fields as touched if you try to submit and you have client-side validation errors, thus making the errors appear (if you have hidden them when !touched). But the secondary reason is that it won't block submission like happens in the sandbox shared above.

Elegant-Bird commented 1 year ago

Bump. Any update on this? If @ignatevdev has written a package as a workaround, perhaps that logic can be used in the react-final-form package to fix the problem?