question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Async validator on unregister set validating to true

See original GitHub issue

Are you submitting a bug report or a feature request?

bug report

What is the current behavior?

On Wizard page we have a step with a field, that has async validator.

After going to next step, the field is unregistered and a new field is registered with a not-async validator.

However, the validating is set to true when entering the step and after it’s changed to false, the FormSpy component is not updated and re-rendered. So, the next button remains disabled.

This behavior was introduced in https://github.com/final-form/react-final-form/pull/766

What is the expected behavior?

When validating is set to false, re-render FormSpy

Sandbox Link

https://codesandbox.io/s/react-final-form-simple-example-0rc9g?fontsize=14&hidenavigation=1&theme=dark

Code

### code


import React from "react";
import { render } from "react-dom";
import Styles from "./Styles";
import { Form, Field, FormSpy } from "react-final-form";

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

const asyncValidator = () => new Promise(res => setTimeout(() => res(), 1000));

const requiredValidator = value => (value ? "" : "required");

class App extends React.Component {
  state = { mounted: false };
  componentDidMount() {
    this.setState({ mounted: true, step: 0 });
  }
  render() {
    return (
      <Styles>
        <Form
          onSubmit={
            this.state.mounted
              ? async values => {
                  await sleep(300);
                  window.alert(JSON.stringify(values, 0, 2));
                }
              : () =>
                  window.alert(
                    "You are incorrectly calling an outdated onSubmit"
                  )
          }
          render={({ handleSubmit, reset, submitting, pristine, values }) => (
            <form onSubmit={handleSubmit}>
              <div>
                {this.state.step === 0 && (
                  <React.Fragment>
                    <label>First Name</label>
                    <Field
                      name="firstName"
                      component="input"
                      type="text"
                      placeholder="First Name"
                      validate={asyncValidator}
                    />
                  </React.Fragment>
                )}
                {this.state.step === 1 && (
                  <React.Fragment>
                    <label>Password Requiered</label>
                    <Field
                      name="password"
                      component="input"
                      type="text"
                      placeholder="12345"
                      validate={requiredValidator}
                    />
                  </React.Fragment>
                )}
              </div>
              <FormSpy>
                {({ validating, submitting, pristine, valid }) => (
                  <div className="buttons">
                    {this.state.step === 0 && (
                      <button
                        type="button"
                        onClick={() => this.setState({ step: 1 })}
                        disabled={validating || !valid || pristine}
                      >
                        Next
                      </button>
                    )}
                    {this.state.step === 1 && (
                      <button
                        type="submit"
                        disabled={validating || submitting || pristine}
                      >
                        Submit
                      </button>
                    )}
                    <button
                      type="button"
                      onClick={reset}
                      disabled={submitting || pristine}
                    >
                      Reset
                    </button>
                    <pre>
                      {JSON.stringify({ values, validating, valid }, 0, 2)}
                    </pre>
                  </div>
                )}
              </FormSpy>
            </form>
          )}
        />
      </Styles>
    );
  }
}
render(<App />, document.getElementById("root"));

What’s your environment?

    "final-form": "^4.19.1",
    "final-form-arrays": "^3.0.2",
    "final-form-focus": "^1.1.2",
    "react-final-form": "^6.4.0",
    "react-final-form-arrays": "^3.1.1"

Node v10.16.0

Issue https://github.com/data-driven-forms/react-forms/issues/431

cc @Hyperkid123

Issue Analytics

  • State:open
  • Created 3 years ago
  • Reactions:3
  • Comments:8

github_iconTop GitHub Comments

1reaction
rvsiacommented, Sep 24, 2020

@Chrisdo82

Not a great workaround (actually it’s a terrible one 😃), but after the unregistering the field with a async validation we trigger form.change('nonsense', 'nonsense') in a timeout to rerender the form. (Just be sure you don’t send the value in your submit.)

0reactions
kgregorycommented, Nov 30, 2021

Found a decent workaround in @alanpoulain’s pull request

  const form = useForm();
  // Pause the validation while the Final Form field is registered to prevent a form state desynchronization bug when using async validators.
  // Since the field is not registered directly because of the introspection, Final Form is using the previous form state (without the field) when notifying after the async validation done during the registration.
  // See also https://github.com/final-form/react-final-form/issues/780.
  form.pauseValidation();
  useEffect(() => {
    form.resumeValidation();
  }, [form]);
Read more comments on GitHub >

github_iconTop Results From Across the Web

Using Custom Async Validators in Angular Reactive Forms
Ocasionally, we want to validate some input in our fields before submission, which will be validated against an asynchronous source.
Read more >
Reactive Form Async Validator is not setting the error to the ...
I'm doing a web application in Angular 10 with a simple form to receive two values that I will be validating them on...
Read more >
Validation Group | Async Validation | JET Developer Cookbook
A validation group tracks and summarizes the current validity state of a group of components. This demo shows how to use oj-validation-group when...
Read more >
Angular: Custom Async Validators - Medium
Angular has a very robust library for handling forms, and especially validation of your form inputs. I previous discussed how to use the ......
Read more >
Angular async validator to validate an input field ... - Trung Vo
Problem · Call the validateCodeName on form submit. · Manually call the validateCodeName each time the code name input changed and do the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found