13

Building React Forms with Schemas and Uniforms

 4 years ago
source link: https://blog.bitsrc.io/building-react-forms-with-schemas-and-uniforms-1fd30dd1344b
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Avoiding boilerplate nightmare by building React forms with schemas and Uniforms.

3MFZzun.jpg!web

Image from pexels.com

If you have used React to develop your web application, you’ll notice that building a form with React is... not fun. It requires a lot of boilerplate code and repetitions.

You need to save user inputs into state, create validation functions and onChange event handler. Because of that, many developers have created form libraries to help make the process of writing forms easier and fun. Each library has its own unique solution to the problem of writing React forms.

For example, Formik helps you build forms by abstracting the process of getting user input into state and validating inputs. It used the same basic concept of controlled components introduced by React, but create just enough abstraction to make building forms painless.

On the other hand, Unform is a form builder library that took the approach of uncontrolled components to make complex forms with nested structure easy. It also supports both React and React Native.

And finally, there’s Uniforms , a form builder library that takes yet another unique approach to solve the pain of writing forms in React. This library enables you to build a fully working form by just writing a schema.

Now hold on a sec! What’s a schema again?

Good question! Let’s look at what a schema is before we talk further about Uniforms.

Regardless of which approach you take, make sure you publish your reusable components to a cloud component hub like Bit.dev. Use it to share, document and organize your reusable assets. It’s another step towards a faster and more pleasant development.

uyM3Ejm.jpg Exploring published React components on Bit.dev

Understanding Schema

In computer programming, a schema is an organization or structure of data that defines what the data should look like. It looks like a list of rules that needs to be met by user inputs, so that the application can know whether the input is right or wrong.

There are many types of schema, but by far JSON schema has the widest adoption rate among developers because it’s platform-independent, simple and easily extensible.

For example, here is a schema to declare that a name must-have a string data type:

const schema = {
  title: "ValidationExample",
  type: "object",
  properties: {
    name: { type: "string" }
  }
};

Now add an object with name property. Let’s call it userData object:

const userData = {
  name: 8
}

Now you can use the schema object to validate userData object. But to do that, you need to use a JSON schema validator library. Luckily, there’s a library called ajv that you can use to do just that. Let’s give it a shot.

Install ajv library by using npm install :

npm install ajv

After the package is installed, write a simple validator by calling on the validate function. Pass in the schema as the first parameter and the data to validate as the second parameter:

import Ajv from "ajv";const ajv = Ajv();
const valid = ajv.validate(schema, userData);
if (valid) {
  console.log("Name is valid");
} else {
  console.log("Name is INVALID!");
  console.log(ajv.errors);
}

ajv.validate will check on the data and see whether it matches the given schema. If the data is invalid, it will return false and store the errors inside ajv.errors as an array of objects.

Here is the fully working validation code:

import Ajv from "ajv";const schema = {
  title: "ValidationExample",
  type: "object",
  properties: {
    name: { type: "string" }
  }
};const userData = {
  name: 8
};const ajv = Ajv();
const valid = ajv.validate(schema, userData);
if (valid) {
  console.log("Name is valid");
} else {
  console.log("Name is INVALID!");
  console.log(ajv.errors);
}

Now if you try this code and inspect your console, you’ll find that “Name is INVALID!” is printed in it along with the errors object.

And that’s how a schema work in a nutshell. Let’s see how we can build forms by only writing a schema with Uniforms.

Let’s build a simple uniforms form

Now that you understand what a schema is, let’s try to create a form by loading a schema into uniforms. Here’s a working demo:

First, you need to install the required libraries along with ajv :

npm install uniforms uniforms-bridge-json-schema uniforms-unstyled ajv
uniforms
uniforms-bridge-json-schema
uniforms-unstyled

Once these packages are installed, create a new file named ContactUsSchema.js . You will write your schema and validator code inside this file. First, import the necessary packages and write the schema of the form. In this schema, you need to include required option so that the inputs can’t be empty:

import Ajv from "ajv";
import { JSONSchemaBridge } from "uniforms-bridge-json-schema";const contactUsSchema = {
  title: "Contact Us",
  type: "object",
  properties: {
    fullname: { type: "string" },
    email: { type: "string", format: "email" },
    message: {
      type: "string"
    }
  },
  required: ["fullname", "email", "message"]
};

Next, write the validator using ajv library:

const ajv = new Ajv();function createValidator(contactUsSchema) {
  const validator = ajv.compile(contactUsSchema);  return input => {
    validator(input);  if (validator.errors && validator.errors.length) {
      let errorMessage = { details: validator.errors };
      throw errorMessage;
    }
  };
}const schemaValidator = createValidator(contactUsSchema);

With the schema and validator both ready to use, pass them into JSONSchemaBridge function so that uniform can use it to generate a form. The first parameter will be the schema, and the second should be the validator. You need to export the compiled object so that it can be used by your React app:

export default new JSONSchemaBridge(contactUsSchema, schemaValidator);

Finally, you need to import the schema and use it in your React app, just like this:

import React from "react";
import { AutoForm } from "uniforms-unstyled";import contactUsSchema from "./ContactUsSchema";export default function App() {
  return (
    <div className="m-3">
      <AutoForm
        schema={contactUsSchema}
        onSubmit={input => alert(JSON.stringify(input, null, 2))}
      />
    </div>
  );
}

In the code above, AutoForm is the magic component that takes the compiled schema and turn it into a form. The function inside onSubmit props will only run when the data is valid.

And that’s all you need to do to write a form with uniforms. Isn’t that neat? One thing you might notice is that the validator immediately returns the first error it encountered rather than validating all form inputs first. You can change this by adding the allErrors option when you create a new ajv instance in your schema file:

const ajv = new Ajv({ allErrors: true });

The validator will now always validate all form inputs before returning errors.

Adding Bootstrap support to uniforms

Uniforms support popular styling libraries like Semantic UI, Ant Design, Material UI and Bootstrap. To use a form styled in one of these libraries, you just need to install both uniforms theme and the corresponding design library. For example, let’s use uniforms Boostrap 4 theme:

npm install uniforms-bootstrap4 bootstrap

Now in your React app, import the bootstrap CSS file and change the AutoForm import from uniforms-unstyled to uniforms-bootstrap4:

import "bootstrap/dist/css/bootstrap.min.css";
import { AutoForm } from "uniforms-bootstrap4";

Now, your form will use Bootstrap 4 styling instead of the default form style. You can do the same with the other supported design libraries.

Conclusion

Uniforms is a unique form builder library that allows you to generate a fully functional form by simply writing the data schema. Once the schema is set, you just need to send it over to the schema bridge. Then, the code uniforms library will use the bridge to operate on the schema, validate it, and generate errors if any.

Uniforms also support complex form generation through its APIs. And if that’s still not enough, you can extend its forms and fields to match your project requirements. So if you’re interested in using it for your projects, be sure to check out Uniforms documentation for further learning.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK