DEV Community

Sebastian Messier
Sebastian Messier

Posted on • Originally published at webdevwithseb.com on

How I Build Forms Quickly in React

Forms are everywhere in web apps. Whenever you log in, make a post on social media, or buy something online, you’re using a form.

Despite their ubiquity, building forms requires a lot of attention and care. Form fields should only accept specific types of data, perform validations, and show errors on invalid input. As more fields are added, the complexity of the form grows.

This work is repetitive and tiring. Wouldn’t it be great if we could make form building trivial?

Enter RJSF

I’ve tried lots of form libraries, but none solve the burden of easy, rapid form building as well as RJSF does.

What makes forms difficult is the management of JSX, state, validations, and errors. As you add more fields, you also need to manage more of the aforementioned things, which can get overwhelming fast.

RJSF solves this by being a declarative form builder. Instead of manually defining the form and validation logic, you describe your form using json-schema, and RJSF handles the rest.

I’ve been using it in production with my clients to great effect. To show you how it works, we’ll make a quick sign up form. Familiarity with json-schema is helpful, so here is a 5 minute primer.

Making a Sign Up Form

We first need to collect the user’s email and password. This is what the RJSF react code looks like:

<Form
  schema={{
    title: "Signup",
    properties: {
      email: {
        type: "string"
      },
      password: {
        type: "string"
      }
    }
 }}
/>
Enter fullscreen mode Exit fullscreen mode

From this small bit of code, RJSF has built a heading, text inputs, and submit button. Cool, but this is far from done. Some improvements we can make:

  • Make email and password required fields
  • Enforce minimum password length
  • email field should only accept emails
  • password input should be obfuscated

Let’s add these in.

Make email and password required fields:

<Form
  schema={{
    title: "Signup",
    properties: {
      email: {
        type: "string"
         },
      password: {
        type: "string"
      },
    },
    required: ["email", "password"]
  }}
/>
Enter fullscreen mode Exit fullscreen mode

Enforce minimum password length

<Form
  schema={{
  title: "Signup",
  properties: {
    email: {
      type: "string"
    },
    password: {
      type: "string",
      minLength: 8
    },
  },
  required: ["email", "password"]
}}
/>
Enter fullscreen mode Exit fullscreen mode

email field should only accept emails

<Form
  schema={{
    title: "Signup",
    properties: {
      email: {
        type: "string"
      },
      password: {
        type: "string",
        minLength: 8
      },
    },
    required: ["email", "password"]
  }}
  uiSchema={{
    "email": {
      "ui:widget": "email"
    }
  }}
/>
Enter fullscreen mode Exit fullscreen mode

password input should be obfuscated itself

<Form
  schema={{
    title: "Signup",
    properties: {
      email: {
        type: "string"
      },
      password: {
        type: "string",
        minLength: 8
      },
    },
    required: ["email", "password"]
  }}
  uiSchema={{
    "email": {
      "ui:widget": "email"
    },
    "password": {
      "ui:widget": "password"
    }
  }}
/>
Enter fullscreen mode Exit fullscreen mode

And here is the final result (View the code here.)

RJSF supports HTML native error handling, as well as custom JS error handling.

What Else Can RJSF Do?

This is just scratching the surface. RJSF has much more to offer.

Themes

Native support for popular libraries like chakra, semantic-ui, material design, and more.

Complex Fields

Multi-select dropdowns, check boxes, configurable lists, and much more are supported out of the box. If you need, you can also create your own custom form fields.

Custom Validations & Errors

Add custom validations to your form. Here is a custom “password match” validation:

<Form 
  validate={(formData, errors) => {
    if (formData.pass1 !== formData.pass2) {
      errors.pass2.addError("Passwords don't match");
    }
    return errors;
  }}
  schema={{
    type: "object",
    properties: {
      pass1: {type: "string", minLength: 3},
      pass2: {type: "string", minLength: 3},
    }
  }}
/>
Enter fullscreen mode Exit fullscreen mode

What are the RJSF Cons?

While RJSF is great, it also comes with downsides:

RJSF is fantastic if you're still figuring out the data your form is collecting. However, the docs mention that "if you have a priori knowledge of your data and want a toolkit for generating forms for it, you might want to look elsewhere".

Conclusion

This was a quick dive into RJSF, my favorite react library for rapid form development.

If you’d like to try it out, check out this playground. It has tons of examples that show the power of RJSF. If you dig it, help the maintainers out by giving them a star on GitHub

The post The Best React Form Library (2022) first appeared on 💻 Web Dev With Seb.

Top comments (0)