Overview

We use the react-hook-form library along with @hookform/resolvers to simplify the process of creating and managing forms. This setup allows for the quick development of robust forms.

Form Schema

With @hookform/resolvers, you can validate your forms using a Zod schema. Just write the schema and use it as a resolver in the useForm hook. This approach not only validates your forms but also helps in creating perfectly typed forms by inferring types from the schema.

Example of setting up a form with Zod schema:

import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

// Define your schema
const schema = z.object({
  firstName: z.string().min(1, 'Please enter First name').max(100),
  lastName: z.string().min(1, 'Please enter Last name').max(100),
  email: z.string().regex(EMAIL_REGEX, 'Email format is incorrect.'),
});

// Infer type from schema
type FormParams = z.infer<typeof schema>;

const Page = () => {
  const { register, handleSubmit } = useForm<FormParams>({
    resolver: zodResolver(schema),
  });

  // Form handling code here
};

Error Handling

For error handling in forms, we use the handle-error.util.ts utility function. This function parses error messages, sets them to the form fields’ error states, or displays a global notification for general errors.

Usage:

import { useForm } from 'react-hook-form';
import { handleError } from 'utils';

const Page: NextPage = () => {
  const { setError } = useForm();

  // Submit function
  const onSubmit = (data: SignUpParams) => signUp(data, {
    onError: (e) => handleError(e, setError),
  });
}

Form usage

Here is an example of how you can create a form:

import { handleError } from 'utils';
import { accountApi } from 'resources/account';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';

// Define your schema
const schema = z.object({
  // Schema details here
});

// Infer type from schema
type SignUpParams = z.infer<typeof schema>;

const Page: NextPage = () => {
  const { mutate: signUp, isLoading: isSignUpLoading } = accountApi.useSignUp();
  const {
    register,
    handleSubmit,
    setError,
    formState: { errors },
  } = useForm<SignUpParams>({
    resolver: zodResolver(schema),
  });

  // Submit function
  const onSubmit = (data: SignUpParams) => signUp(data, {
    onSuccess: (data) => {
      // Handle success response
      queryClient.setQueryData(['account'], data);
    },
    onError: (e) => handleError(e, setError),
  });

  // Form rendering
  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <TextInput
        {...register('name')}
        error={errors.name?.message}
      />

      <Button
        type="submit"
        loading={isSignUpLoading}
      >
        Submit
      </Button>
    </form>
  );
};

By following these guidelines, you can effectively build and manage forms in our application, ensuring a smooth user experience and robust form handling.