Revalidation strategies

Compare onChange and onBlur revalidation strategies. These can not be combined, however live fields might be a viable supplement depending on form and validation complexity.

onChange strategy (default)

If there is a validation error, invalid inputs will revalidate on every change until the error is resolved. This does not revalidate the entire form.

User registration
import React from "react";
import { useBrowserForm, ValidationError, ValidationSchema } from "react-browser-form";

// UI for documentation only
import { Button, Stack } from "react-bootstrap";
import { FormGroup, FormGroupTitle, FormTextInput } from "ui/forms";
import { FormPassword } from "ui/forms/FormPassword";

// FORM SETUP AND VALIDATION
// --------------------------------------------------------------------------------

const defaultValues = {
  name: "",
  email: "",
  newPassword: "",
};
type Form = typeof defaultValues;

const validationSchema: ValidationSchema<Form> = {
  validators: {
    name: name => {
      if (name.length < 5) throw new ValidationError("Name must be at least 5 characters long");
    },

    email: email => {
      if (!email.match(/^\S{2,}@\S{2,}\.\S{2,}$/)) throw new ValidationError("E-mail must match pattern xx@xx.xx");
    },

    newPassword: newPassword => {
      if (!newPassword.match(/[a-z]/))
        throw new ValidationError("Password must contain at least one lowercase letter.");
      if (!newPassword.match(/[A-Z]/))
        throw new ValidationError("Password must contain at least one UPPERCASE letter.");
      if (!newPassword.match(/[0-9]/)) throw new ValidationError("Password must contain at least one number.");
      if (newPassword.length < 8) throw new ValidationError("Password must be at least 8 characters long.");
    },
  },
};

// COMPONENT
// --------------------------------------------------------------------------------

export function ExampleRevalidationStrategyOnChange() {
  const [data, setData] = React.useState<Form>();

  const { formProps, names, errorData } = useBrowserForm<Form>({
    name: "example-revalidation-strategy-onchange",
    revalidationStrategy: "onChange",
    defaultValues,
    onSubmit: setData,
    validationSchema,
    validateAfterInit: true,
  });

  const { errors } = errorData;

  return (
    <form {...formProps}>
      <FormGroupTitle>User registration</FormGroupTitle>
      <FormGroup>
        <FormTextInput label="Name" requiredMark name={names.name} error={errors.name} />
        <FormTextInput label="E-mail" requiredMark name={names.email} error={errors.email} />
      </FormGroup>
      <FormPassword label="Password" requiredMark name={names.newPassword} error={errors.newPassword} />

      <Stack direction="horizontal" className="justify-content-end mt-5">
        <Button type="submit" disabled={errorData.count > 0}>
          Submit registration
        </Button>
      </Stack>
    </form>
  );
}
Form meta
Submitted?
No
Has errors?
No
Is dirty?
No
Change reason
Form state

onBlur strategy

On blur is suitable for when your validation or form is resource-heavy or complex or you do not require live feedback for revalidating. This makes it very fast.

User registration
import React from "react";
import { useBrowserForm, ValidationError, ValidationSchema } from "react-browser-form";

// UI for documentation only
import { Button, Stack } from "react-bootstrap";
import { FormGroup, FormGroupTitle, FormTextInput } from "ui/forms";
import { FormPassword } from "ui/forms/FormPassword";

// FORM SETUP AND VALIDATION
// --------------------------------------------------------------------------------

const defaultValues = {
  name: "",
  email: "",
  newPassword: "",
};
type Form = typeof defaultValues;

const validationSchema: ValidationSchema<Form> = {
  validators: {
    name: name => {
      if (name.length < 5) throw new ValidationError("Name must be at least 5 characters long");
    },

    email: email => {
      if (!email.match(/^\S{2,}@\S{2,}\.\S{2,}$/)) throw new ValidationError("E-mail must match pattern xx@xx.xx");
    },

    newPassword: newPassword => {
      if (!newPassword.match(/[a-z]/))
        throw new ValidationError("Password must contain at least one lowercase letter.");
      if (!newPassword.match(/[A-Z]/))
        throw new ValidationError("Password must contain at least one UPPERCASE letter.");
      if (!newPassword.match(/[0-9]/)) throw new ValidationError("Password must contain at least one number.");
      if (newPassword.length < 8) throw new ValidationError("Password must be at least 8 characters long.");
    },
  },
};

// COMPONENT
// --------------------------------------------------------------------------------

export function ExampleRevalidationStrategyOnBlur() {
  const [data, setData] = React.useState<Form>();

  const { formProps, names, errorData } = useBrowserForm<Form>({
    name: "example-revalidation-strategy-onblur",
    revalidationStrategy: "onBlur",
    defaultValues,
    onSubmit: setData,
    validationSchema,
    validateAfterInit: true,
  });

  const { errors } = errorData;

  return (
    <form {...formProps}>
      <FormGroupTitle>User registration</FormGroupTitle>
      <FormGroup>
        <FormTextInput label="Name" requiredMark name={names.name} error={errors.name} />
        <FormTextInput label="E-mail" requiredMark name={names.email} error={errors.email} />
      </FormGroup>
      <FormPassword label="Password" requiredMark name={names.newPassword} error={errors.newPassword} />

      <Stack direction="horizontal" className="justify-content-end mt-5">
        <Button type="submit" disabled={errorData.count > 0}>
          Submit registration
        </Button>
      </Stack>
    </form>
  );
}
Form meta
Submitted?
No
Has errors?
No
Is dirty?
No
Change reason
Form state