Skip to content

useForm setError typing seems wrong #2214

Open
@axelvaindal

Description

@axelvaindal

Version:

  • @inertiajs/react version: latest

Describe the problem:

When using useForm in a react application, we have access to the function setError which has two overrides : one with a single error key and value, and another with an error object. The error object seems wrongly typed, because it assumes we always pass all key / value pair in the errors, which does not reflect the reality when used with validation libraries.

This is the current type 👇

errors: Record<keyof TForm, string>

It should probably be 👇

errors: Partial<Record<keyof TForm, string>>

In the same spirit, we currently create a lot of boilerplate code just to prevent sending the form when using validation librairies like zod/yup/joi etc. Would it be possible to consider accepting a resolver in the useForm hook configuration to prevent the sending of the form in case of validations error ? It would avoid unnecessary requests to the server and improve the DS similarly to what react-hook-form accepts.

Here is my current implementation with Yup as a reference 👇

function useValidatedForm<T extends Record<string, FormDataConvertible>>(schema: Schema, initialData?: T) {
  const form = useForm<T>(initialData);

  const isValid = useCallback(
    (data: T, schema: Schema) => {
      try {
        form.clearErrors();
        schema.validateSync(data, { abortEarly: false });
        return true;
      } catch (errors: any) {
        const validationErrors: Partial<Record<keyof T, string>> = {};

        errors.inner.forEach((error: ValidationError) => {
          if (error.path !== undefined) {
            validationErrors[error.path as keyof T] = error.errors[0];
          }
        });

        form.setError(validationErrors as Record<keyof T, string>);
        return false;
      }
    },
    [form],
  );

  const submit = useCallback(
    (method: Method, url: string, options?: VisitOptions) => {
      return form.submit(method, url, {
        ...options,
        onBefore: (visit) => {
          if (!isValid(form.data, schema)) {
            return false;
          }

          if (options?.onBefore) {
            return options.onBefore(visit);
          }
        },
      });
    },
    [form, schema, isValid],
  );

  return {
    ...form,
    submit,
  };
}

Steps to reproduce:

  • Call setError with an error object containing a single key/value pair -> TS errors

Metadata

Metadata

Assignees

No one assigned

    Labels

    reactRelated to the react adapter

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions