✨ useFormik Composable

The useFormik composable is your ultimate ally for managing complex forms in Vue 3 applications. With its simplicity and efficiency, it provides:

  • ⚑ Reactive state management
  • βœ… Schema-based validation (supporting libraries like Yup)
  • πŸš€ Streamlined form submission handling

With useFormik, you can effortlessly create dynamic, user-friendly forms that deliver a robust and consistent user experience.

Performance:

Form validation runs deeply on every value change. To keep things snappy, optimize your validation schema and rules.

πŸ› οΈ Parameters

ParameterTypeRequiredDefaultDescription
initialValuesobject: <T>true-An object containing the initial values for the form fields.
yupSchemaObjectSchema<T>false-A yup schema for validating the form fields.
joiSchemaObjectSchema<T>false-A joi schema for validating the form fields.
zodSchemaZodType<T>false-A zod schema for validating the form fields.
validationSchemaFormikValidationSchema<T>false-A custom validation rules object for validating the form fields.
onSubmitFormikOnSubmit<T>false-A function to handle form submission. It receives the current form values and helpers.
validateOnMountbooleanfalsetrueIf true, performs validation when the form is initialized.
preventDefaultbooleanfalsetrueIf true, prevents the default form submission behavior.

πŸ”— Notes:

The validation schema can be supplied as yupSchema, joiSchema, zodSchema or validationSchema parameters.

If any of the schema parameters are not provided, the form will not perform any validation.

Please use Object schemas for Yup and Joi and not the string schemas.

Parameters for onSubmit handler

TYPE: (FormikOnSubmit<T> = values: T, helpers: FormikHelpers<T>)

When the onSubmit function is invoked by the submit handler, it receives two arguments: values and helpers.

The values argument is an object that contains the current values of the form fields.

The helpers argument is an object that contains a set of utility functions that can be used to interact with the form state.

  1. reset - Resets the form to its initial state.
  2. setErrors - Sets the errors for the form fields.
  3. setValues - Sets the values for the form fields.
  4. setSubmitting - Sets the submitting state of the form.

πŸ—οΈ Properties

PropertyTypeDescription
valuesreactive<T>Reactive object containing the current values of form fields.
errorsreactive<object>Reactive object containing field-level validation errors.
touchedreactive<object>Reactive object indicating whether a field has been interacted with.
isValidcomputed<boolean>Computed property indicating if the form is valid.
isDirtycomputed<boolean>Computed property indicating if the form values have changed from the initial values.
isSubmittingref<boolean>Ref indicating if the form is in the submitting state.
isValidatingref<boolean>Ref indicating if the form is in the validating state.
submitCountref<number>Ref containing the number of form submission attempts.
fieldHandlerscomputed<object>Handlers (onBlur and onChange) for form fields.

πŸ”— Notes:

  1. Reactivity: Values, errors, and touched objects are fully reactive, enabling two-way data binding with form fields.
  2. Computed properties: isValid & isDirty are computed properties. Don't forget to use .value while accessing it inside the template.

βš™οΈ Methods

MethodParametersDescription
setValues(newValues: Partial<T>)Updates the form values.
setErrors(newErrors: object)Updates the form errors.
setTouched(newTouched: object)Updates the form’s touched state.
reset({ values }: { values?: Partial<T> })Resets the form to the initial state or provided values.
setFieldValue(field: string, value: unknown)Updates the value of a specific field.
setFieldTouched(field: string, touchedValue: boolean)Marks a specific field as touched.
setSubmitting(value: boolean)Updates the submitting state.
handleSubmit(e: Event)Handles form submission, triggers validation, and executes onSubmit.
handleFieldBlur(e: FocusEvent)Marks the corresponding field as touched on blur.
handleFieldChange(e: Event)Updates the corresponding field’s value and marks it as touched on change.
hasFieldError(field: string): booleanChecks if a specific field has an error and has been touched.
getFieldError(field: string): stringRetrieves the error message for a specific field if it exists.
getFieldValue(field: string): unknownRetrieves the current value of a specific field.
getFieldTouched(field: string): boolean|undefinedChecks if a specific field has been touched.

🌟 Dynamic Fields:

  1. setFieldValue: Dynamically update specific field values.
  2. setFieldTouched: Dynamically update the touched state of specific fields.
  3. ⚠️ setFieldError: This method is NOT available. Errors are handled internally through validation rules in the schema.

πŸ” Custom Validation

You can define custom validation rules using the validationSchema parameter. These rules can validate simple fields, arrays, objects, or even arrays of objects.

Example

const initialValues = {
  email: "",
  password: "",
  confirmPassword: "",
}
const validationSchema = {
  email: (value: string) => {
    if (!value) {
      return "Email is required";
    }
    if (!isEmail(value)) {
      return "Invalid email";
    }
  },
  password: (value: string) => {
    if (!value) {
      return "Password is required";
    }
    if (value.length < 8) {
      return "Password must be at least 8 characters";
    }
  },
  confirmPassword: (value: string) => {
    if (!value) {
      return "Confirm password is required";
    }
    if (value !== initialValues.password) {
      return "Passwords do not match";
    }
  },
}

The above example shows a validation schema for the email and password fields. - **Email** must be valid and is required. - **Password** must be at least 8 characters long and is required.

Validation schemas can be customized to handle simple fields or more complex structures, such as arrays or nested objects.

πŸ’‘ My form values aren’t always strings

No worries! Validation rules can be written for arrays, objects, or even arrays of objects.

const initialValues = {
  email: [""],
}
const validationSchema = {
  email: (values: string[]) => {
    if (!values?.length) {
      return "Email is required";
    }
    const errs = [];
    values.forEach((value, index) => {
      if (!value) {
        errs.push("Email is required");
        return; // Skip further validation
      }
      if (!isEmail(value)) {
        errs.push("Invalid email");
      }
    });
  }
}

In the example above, the emails field is an array of email addresses. Each email is validated, and errors are displayed if any email is invalid.

For more complex validation rules, check out the playground section. πŸ”—