🔥 5 Best Libraries to Develop React.js Forms 2024

ansonch

Anson Ch

Posted on January 31, 2024

🔥 5 Best Libraries to Develop React.js Forms 2024

For a while now, I have been using React at the company I work for, catering to consumer facing and back-office applications across industries. We deal a lot with forms of different level of complexities. To shorten form development time, our company recommends us to use React Hook Form library (a form library). I have always wondered if there are better alternatives but because of the nature of my work, I previously didn't have the time to explore. So during the down time at the end of the year, I manage to find some time to look into different form libraries.

In this article, we will explore five popular form libraries for React.js projects: React Hook Form, Formik, Ant Design (AntD), TanStack, and React Final Form. Each of these libraries has its own unique features and capabilities, making them suitable for different types of projects and use cases.


Supercharge Your React App with React PDF

Before we dive into form libraries, here’s a quick update on something I’m working on. React PDF is a powerful library for rendering and customizing PDF documents directly in your React applications. With a wide range of features, including theme customization, localization, and responsive layouts, React PDF makes integrating PDFs a breeze.

React PDF

If your project involves working with PDFs, whether for reports, documents, or dashboards, take a look at React PDF. It’s designed to make PDF handling fast and easy in any React setup.


Why are forms important?

Forms are an essential part of web applications, and React.js projects are no exception. They enable users to share information, complete tasks, and provide feedback. Without forms, many of the tasks that we take for granted on the web, such as logging in, signing up, or making purchases, would not be possible. Moreover, forms can manage component state and component reactivity very effectively by using the capabilities provided by various libraries. As such, learning how to create effective and user-friendly forms is essential for developers looking to build engaging and interactive web applications.


React Hook Form

react hook form
React Hook Form (RHF) is easy to use and requires minimal boilerplate code from developers because it is built on top of the React hooks. A lightweight package with simple-to-use API that mainly focuses on performance and minimal re-renders. It can use both controlled (states) and uncontrolled inputs (refs) making RHF more flexible than other libraries.

Key Features

  1. Easy Form Creation and Management
    You can simply create and manage the form using the RHF library. It will require very little coding and reduce the need for state management.

  2. Built-in Validation Mechanism
    The React Hook form offers API options that follow the existing HTML standard for form validation, and you can create your own validation rules as well.

Using the RHF library, here is a development example of a basic form.

import { useCallback } from "react"; 
import { useForm } from "react-hook-form"; 

export const RHF = () => { 
  const { 
    register, 
    handleSubmit, 
    getValues, 
    formState: { errors }, 
  } = useForm(); 

  const onSubmit = useCallback(() => { 
    console.log(getValues()); 
  }, [getValues]); 

  return ( 
    <> 
      <h2>React Hook Form</h2> 
      <form onSubmit={handleSubmit(onSubmit)}> 
        <label htmlFor="firstname">First name</label> 
        <div> 
          <input 
            placeholder="First name" 
            {...register("firstname", { required: "this field is required" })} 
          /> 
        </div> 
        <div className="error-message">{errors.firstname?.message}</div> 
        <label htmlFor="lastname">Last name</label> 
        <div> 
          <input 
            placeholder="Last name" 
            {...register("lastname", { required: "this field is required" })} 
          /> 
        </div> 
        <div className="error-message">{errors.lastname?.message}</div> 
        <button type="submit">Submit</button> 
      </form> 
    </> 
  ); 
}; 
Enter fullscreen mode Exit fullscreen mode

React Hook Form - Form Development Demo


Formik

Formik
Formik is an open-source tool built to increase the efficiency of managing form state, handling submissions and validating forms in React apps. For Example, traditionally, we handle forms in React by creating a useState() hook for each form field, adding event listeners and updating fields individually. Formik takes care of this by handling all that logic for us; we only need to import its components, giving us an easy way to access our form data. It is worth noting that although Formik was not maintained for the past two years, it has only recently been picked up again in late 2023.

Key Features

  1. Easy Form Generation
    Form, Field, and ErrorMessage are just a few of the tools and components that come with Formik and offer a simple and recognizable method of configuring and controlling the form state.

  2. Validation of Forms
    While there are numerous methods for utilizing Formik to validate the form, you can also utilize JavaScript functions or basic HTML input validation parameters like required and minlength.

  3. Using Yup to Integrate Complex Validation Schemas
    Yup, a JavaScript schema builder that handles value parsing and validation can be integrated with Formik. This makes it possible to create complex validation rules and custom error messages, which improves the form validation process.

Here is a development example of a basic form using the Formik library.

import { Formik, Field, Form, ErrorMessage } from "formik"; 
import * as Yup from "yup"; 

const SignUpSchema = Yup.object().shape({ 
  firstName: Yup.string().required("This field is required"), 
  lastName: Yup.string().required("This field is required"), 
}); 

export const FormikForm = () => ( 
  <div className="formik-form"> 
    <h2>Formik</h2> 
    <Formik 
      initialValues={{ 
        email: "", 
        firstName: "", 
        lastName: "", 
      }} 
      validationSchema={SignUpSchema} 
      onSubmit={(values) => { 
        setTimeout(() => { 
          alert(JSON.stringify(values, null, 2)); 
        }, 500); 
      }} 
      render={({ errors, touched }) => ( 
        <Form> 
          <label htmlFor="firstName">First name</label> 
          <div> 
            <Field name="firstName" placeholder="First name" type="text" /> 
            <ErrorMessage 
              name="firstName" 
              component="div" 
              className="error-message" 
            /> 
          </div> 

          <label htmlFor="lastName">Last name</label> 
          <div> 
            <Field name="lastName" placeholder="Last name" type="text" /> 
            <ErrorMessage name="lastName"> 
              {(msg) => <div className="error-message">{msg}</div>} 
            </ErrorMessage> 
          </div> 
          <button type="submit">Submit</button> 
        </Form> 
      )} 
    /> 
  </div> 
); 
Enter fullscreen mode Exit fullscreen mode

Formik - Form Development Demo


Ant Design (AntD)

Ant Design
AntD is a UI framework that is the second most popular in the world because it provides high-quality React components, including a set of built-in typescript forms and validations. Unlike the other libraries mentioned in this article, AntD is a full UI library that offers a comprehensive suite of design elements along with forms and validations. It can support many different browsers, server-side rendering and electron environments. Unlike other UI libraries that would need additional plugins or extensions for some functionalities, AntD put all these key features into its core framework.

Key Features

  1. Form Creation
    AntD provides a variety of data entry elements such as Input, Radio, Checkbox, etc, allowing different form designs.

  2. Form Validation
    Maintains the integrity of data by applying comprehensive validation rules.

  3. CSS-in-JS Technology
    It uses CSS-in-JS in its design to enable dynamic and mixed theme capabilities, hence allowing for more flexible style management.

Using the AntD library, here is a development example of a basic form.

import { Button, Form, Input, Flex } from "antd"; 

export const Antd = () => { 
  const onFinish = (values) => { 
    console.log(values); 
  }; 

  return ( 
    <Flex vertical> 
      <h2>Ant Design</h2> 
      <Form 
        name="normal_login" 
        initialValues={{ remember: true }} 
        onFinish={onFinish} 
      > 
        <Form.Item 
          name="firstname" 
          rules={[{ required: true, message: "This field is required" }]} 
        > 
          <Input placeholder="First name" /> 
        </Form.Item> 
        <Form.Item 
          name="lastname" 
          rules={[{ required: true, message: "This field is required" }]} 
        > 
          <Input placeholder="Lastname" /> 
        </Form.Item> 

        <Form.Item> 
          <Button 
            type="primary" 
            htmlType="submit" 
            className="login-form-button" 
          > 
            Submit 
          </Button> 
        </Form.Item> 
      </Form> 
    </Flex> 
  ); 
}; 
Enter fullscreen mode Exit fullscreen mode

Ant Design - Form Development Demo


TanStack

TanStack
TanStack is not just a single library. It is actually a set of open-source libraries that are highly reliable. It has a variety of headless, type-safe, powerful utilities for web developers, such as state management, routing, data visualization, charts, tables, rather than focusing solely on UI components.

Key Features

  1. Form Creation
    TanStack Forms makes it easy to create form layouts. The forms can have different types and structures of fields, and fields can also be added or removed dynamically within a form.

  2. Form Validation
    TanStack Provides a set of predefined validation rules that can apply to the form fields so that it can generate data integrity. Also, it allows the implementation of custom validation logic, which permits the developer to define complex validation criteria.

Here is a development example of a basic form using the TanStack library.

import { useForm } from "@tanstack/react-form"; 

function FieldInfo({ field }) { 
  return ( 
    <> 
      {field.state.meta.touchedErrors ? ( 
        <div className="error-message">{field.state.meta.touchedErrors}</div> 
      ) : null} 
      {field.state.meta.isValidating ? "Validating..." : null} 
    </> 
  ); 
} 

export function TanStack() { 
  const form = useForm({ 
    defaultValues: { 
      firstName: "", 
      lastName: "", 
    }, 
    onSubmit: async ({ value }) => { 
      setTimeout(() => { 
        alert(JSON.stringify(value, null, 2)); 
      }, 500); 
    }, 
  }); 

  return ( 
    <div className="tanstack-form"> 
      <h2>TanStack</h2> 
      <form.Provider> 
        <form 
          onSubmit={(e) => { 
            e.preventDefault(); 
            e.stopPropagation(); 
            void form.handleSubmit(); 
          }} 
        > 
          <div> 
            <form.Field 
              name="firstName" 
              validators={{ 
                onChange: ({ value }) => 
                  !value ? "This field is required" : undefined, 
              }} 
              children={(field) => { 
                return ( 
                  <> 
                    <label htmlFor={field.name}>First name</label> 
                    <div> 
                      <input 
                        id={field.name} 
                        name={field.name} 
                        value={field.state.value} 
                        onBlur={field.handleBlur} 
                        placeholder="First name" 
                        onChange={(e) => field.handleChange(e.target.value)} 
                      /> 
                    </div> 
                    <FieldInfo field={field} /> 
                  </> 
                ); 
              }} 
            /> 
          </div> 
          <div> 
            <form.Field 
              name="lastName" 
              validators={{ 
                onChange: ({ value }) => 
                  !value ? "This field is required" : undefined, 
              }} 
              children={(field) => ( 
                <>
                  <label htmlFor={field.name}>Last name</label> 
                  <div> 
                    <input 
                      id={field.name} 
                      name={field.name} 
                      value={field.state.value} 
                      onBlur={field.handleBlur} 
                      placeholder="Last name" 
                      onChange={(e) => field.handleChange(e.target.value)} 
                    /> 
                  </div> 
                  <FieldInfo field={field} /> 
                </> 
              )} 
            /> 
          </div> 
          <form.Subscribe 
            selector={(state) => [state.canSubmit, state.isSubmitting]} 
            children={([canSubmit, isSubmitting]) => ( 
              <button type="submit" disabled={!canSubmit}> 
                {isSubmitting ? "..." : "Submit"} 
              </button> 
            )} 
          /> 
        </form> 
      </form.Provider> 
    </div> 
  ); 
} 
Enter fullscreen mode Exit fullscreen mode

TanStack - Form Development Demo


React Final Form

React Final Form
React Final Form provides a straightforward way to handle form state and validation with minimal impact on performance. It is a wrapper around Final Form with no dependencies. It follows an observer design pattern in which components subscribe to specific events that cause fewer re-renders instead of re-rendering the whole form. It is similar to the useEffect() hook in React that watches the values. React Final Form is wired up to provide validation, state management, and event handling with minimal configuration.

Key Features

  1. Form Validation
    React Final Form supports a variety of validation methods along with the custom validation engine. At a high level, it provides two types of validations:

    **Field-Level Validation*: This validation runs when any field in the form changes.

    • Form-Level Validation: This validation runs when the form is submitted.
  2. Form Creation
    You can easily set up React Final Form by using and components, and it also provides built-in input types, dynamic fields, wizard forms, custom component creation and integration with other UI Libraries.

  3. Efficient Data Management
    The Library also loads, normalizes, saves, and reinitializes form data to maintain the pristine/dirty state and manage complicated form workflows.

Here is a development example of a basic form using the React Final Form library.

import React from "react"; 
import { Form, Field } from "react-final-form"; 

const onSubmit = async (values) => { 
  console.log(values); 
}; 

export const ReactFinalForm = () => ( 
  <div className="react-final-form"> 
    <h2>React Final Form</h2> 
    <Form 
    onSubmit={onSubmit}     
    validate={(values) => {     
      const errors = {};      
      console.log(values);      
      if (!values.firstname) {       
        errors.firstname = "This field is required";      
      }      
      if (!values.lastname) {      
        errors.lastname = "This field is required";       
      }       
      return errors;     
    }}     
    render={({ submitError, handleSubmit, submitting }) => (     
      <form onSubmit={handleSubmit}>       
        <Field name="firstname">         
        {({ input, meta }) => (        
          <div>           
            <label htmlFor="firstname">First name</label>           
            <div>             
              <input {...input} type="text" placeholder="First name" />               
            </div>           
            <div className="error-message">             
              {meta.touched ? meta.error || meta.submitError : ""}            
            </div>          
          </div>        
        )}         
        </Field>      
        <Field name="lastname">        
        {({ input, meta }) => (        
          <div>          
            <label htmlFor="lastname">Last name</label>        
            <div>            
              <input {...input} placeholder="Last name" />           
            </div>         
            <div className="error-message">          
              {meta.touched ? meta.error || meta.submitError : ""}         
            </div>           
          </div>         
        )}         
        </Field>       
      {submitError && <div className="error">{submitError}</div>}      
        <div className="buttons">         
          <button type="submit" disabled={submitting}>           
          Submit           
          </button>        
        </div>      
      </form>    
    )}  
  />  
  </div>
); 
Enter fullscreen mode Exit fullscreen mode

React Final Form - Form Development Demo


Comparing the five libraries

Five libraries


Conclusion

Choosing the right library depends on specific project needs, as highlighted in our analysis. Considering each library's strengths can guide you to the best fit for your project. It is important to consider the strengths of each Library in the context of your project.

  1. RHF - Choose RHF if you want to have good speed and simplicity with zero dependencies

  2. Formik - Choose Formik if you want a tried and tested solution for form management with a large community and recent updates that have revitalized its maintenance

  3. TanStack - Good option if you need a versatile toolkit for complex form systems and state management within a modular and powerful ecosystem

  4. React Final Form - best fit for performance-centric projects that require lightweight forms with flexible validation and minimal dependencies.

  5. AntD - Go for AntD if you're seeking a comprehensive UI framework that includes a wide range of ready-made components, including robust form elements and validation, for cohesive interface development.

Personally, I will stick with RHF until something that offers significantly better performance and/or functionalities comes along. However, everyone's situation is different, I hope you find my exploration a good starting point. For more information you can start digging further them via the official documentation, which would help you understand which is best for which situation. Such research will enable you to save time and streamline your form development process.


Make PDF Handling Effortless with React PDF

React PDF

If you found this article helpful for your forms, don’t miss another must-have for your React toolkit: React PDF. Whether you’re building a dashboard or managing documents, React PDF allows you to easily display and customize PDFs without the hassle. It’s fast, developer-friendly, and built to handle complex PDF needs, all while staying flexible and light.

Check it out and see how it can simplify PDF handling in your next project!

💖 💪 🙅 🚩
ansonch
Anson Ch

Posted on January 31, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related