DEV Community

Dutchskull
Dutchskull

Posted on

Building a Complex Form with React Hook Form and Yup

Creating forms in web applications can often be a daunting task, especially when it comes to managing state and validation. In this blog post, we will explore how to build a complex form using React Hook Form and Yup for validation, while keeping our code clean and maintainable. For a complete implementation, you can check out the GitHub repository.

Overview of the Form

The form we are building allows users to create a book store by entering the store's name and adding multiple books. Each book entry includes a title, amount, and binding type. This form leverages the power of React Hook Form for state management and Yup for validation, ensuring a smooth user experience.

Key Components

1. Form Component

The main component of our form is responsible for rendering the overall structure and handling form submission. It utilizes useForm from React Hook Form to manage the form state and useFieldArray to handle dynamic book entries.

Key Features:

  • Dynamic Fields: Users can add or remove book entries dynamically.
  • Validation: The form validates user input using Yup, ensuring that all required fields are filled out correctly.

Code Snippet:

const { control, register, handleSubmit, formState: { errors } } = useForm<BookStore>({
  resolver: yupResolver(bookStoreValidationScheme),
  defaultValues: {
    name: "",
    books: [],
  },
});
Enter fullscreen mode Exit fullscreen mode

Why Use This?

Using useForm with a resolver allows us to easily integrate Yup validation into our form. This setup simplifies form state management and ensures that validation rules are applied consistently.

2. BookInputRow Component

This component represents a single row for book input. It allows users to enter details for each book, including the title, amount, and binding type.

Key Features:

  • Autocomplete for Binding Type: Users can select the binding type from a predefined list, enhancing usability.
  • Error Handling: Each input field displays validation messages when the user input is invalid.

Code Snippet:

<Controller
  control={props.control}
  name={`books.${props.index}.binding`}
  render={({ field }) => (
    <Autocomplete
      {...field}
      options={bookTypes}
      onChange={(_, value) => field.onChange(value)}
      renderInput={(params) => (
        <TextField
          {...params}
          label="Book Type"
          error={!!props.errors.books?.[props.index]?.binding}
          helperText={props.errors.books?.[props.index]?.binding?.message}
          fullWidth
        />
      )}
    />
  )}
/>
Enter fullscreen mode Exit fullscreen mode

Why Use This?

The Controller component allows us to integrate third-party components like Autocomplete with React Hook Form. This approach provides a seamless way to manage form state while leveraging the rich features of MUI components.

3. Validation Schema

We define a validation schema using Yup to enforce rules on the form fields. This schema ensures that:

  • The book store name is required.
  • Each book entry must have a title, amount, and binding type.
  • At least one book must be added to the form.

Code Snippet:

export const bookStoreValidationScheme = yup.object().shape({
  name: yup.string().required("Name is required"),
  books: yup.array().of(
    yup.object().shape({
      title: yup.string().required("Book title is required"),
      amount: yup.number().required("Amount is required").positive("Amount must be more than 1").integer("Amount must be an integer"),
      binding: yup.string().required("Book type is required"),
    })
  ).min(1, "You need to add at least one book").required("You need to add at least one book"),
});
Enter fullscreen mode Exit fullscreen mode

Why Use This?

Using Yup for validation allows us to define clear and concise rules for our form fields. This not only improves the user experience by providing immediate feedback but also ensures that the data submitted is valid and meets our requirements.

How to Set Up the Project

To get started with your own implementation, you can clone the repository:

git clone https://github.com/WhiteOlivierus/ReactMuiFormYup.git
cd ReactMuiFormYup
npm install
npm run dev
Enter fullscreen mode Exit fullscreen mode

This will set up the project with all necessary dependencies, and you can start exploring the code.

Conclusion

In this post, we have discussed the key components of a complex form built with React Hook Form and Yup. By leveraging these libraries, we can create forms that are not only functional but also user-friendly and maintainable. For the complete code and further details, be sure to check out the GitHub repository. Happy coding!

Top comments (0)