Introduction to React Final Form Library

In this article, you will learn how to use React Final Form, a popular library for form management. We will cover how the final form works and see its implementation with relevant examples.

What is the React Final Form?

React Final Form is a lightweight Javascript form library that acts as a wrapper around a Final form which is a form state management library. React Final Form uses an observer design pattern in which the components subscribe to specific events. It does not re-render the whole form but only re-renders the subscribed fields.

React final form is a simple wrapper around a final form library. It has zero dependencies, and it is written in pure javascript. It has a modular design that is very simple to use due to its simple form of state management. It encourages us to write code for required functionality rather than unnecessary code per simple form.

Setting Up React Final Form

Let’s set up and test react final forms functionality in our project. Set up a react project and install the final form library by running the following command.

npm install --save final-form react-final-form

After you install the library, import the main components into the file where you want to use the forms. In this example, we use the form in our main App.js file. Therefore, we import two components, Form and Field, from the react-final-form library.

The form is the main component that takes all props necessary to manage our form. The form component mainly accepts the below props:

1. Component: A react component to render for a form.

2. Debug: A callback for debugging that receives the form state and the states of all the fields. It’s called on every state change.

3. Form: If you like to construct your form

4. initialValues: Initial values to pass to your form.

5. onSubmit: a function that gets called after we submit a form.

6. Render: Accepts a component or a custom form to be rendered.

7. Validate: Returns {} or undefined when the values are valid, or an Object of validation errors when the values are invalid.

The field is a component that is used as a wrapper. In addition, it creates a Standalone final form component. The component created by the field has its state and is managed by a Form tag.

Here are some examples of the Fields props that we can use to render a Field:

1. Name: A key of your input from your initialValues object so the field and its input changes & state handling will only occur for that particular key.

2. Type: Type of input field ex: text, number, select, password.

3. Render: To render the input component.

4. Component: Optional. If you are not using ‘input,’ ‘select,’ or ‘textarea,’ it is recommended that you use

5. Validate: A function that takes the field value, all the values of the form, and the metadata about the field and returns an error if the value is invalid or undefined if the value is valid.

6. Children: You can pass your custom input component to the field via children’s props.

ex:
<Field name="myField" someArbitraryOtherProp={42}>

  {props => {

    console.log(props.someArbitraryOtherProp) // would print 42

    return <input {...props.input}/>

  }}

</Field>

Let’s create a simple Email, Password form see the code below for implementation.

import React from "react";

import { render } from "react-dom";

import Styles from "./Styles";

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

const onSubmit = async (values) => {

 console.log(values);

};

const App = () => (

 <Styles>

   <h1>React Final Form - Simple Example</h1>

   <Form

     onSubmit={onSubmit}

     initialValues={{ email: "", password: "" }}

     render={({ handleSubmit, form, submitting, pristine, values }) => (

       <form onSubmit={handleSubmit}>

         <Field name="email">

           {({ input, meta }) => (

             <div>

               <label>Email</label>

               <input {...input} type="text" placeholder="Email" />

               {meta.error && meta.touched && <span>{meta.error}</span>}

             </div>

           )}

         </Field>

         <Field name="password" >

           {({ input, meta }) => (

             <div>

               <label>Password</label>

               <input {...input} type="password" placeholder="Password" />

               {meta.error && meta.touched && <span>{meta.error}</span>}

             </div>

           )}

         </Field>

         <div className="buttons">

           <button type="submit" disabled={submitting || pristine}>

             Submit

           </button>

           <button

             type="button"

             onClick={form.reset}

             disabled={submitting || pristine}

           >

             Reset

           </button>

         </div>

       </form>

     )}

   />

 </Styles>

);

render(<App />, document.getElementById("root"));

Hire Our Expert React Js Developers

Validation in Final Form

 There are 2 types of validations provided in React Final Form.

1. Form Level Validation: This validation runs after the form is submitted

2. Field Level Validation: This validation runs when we change the field.

We cover both validations for the same email and password form in section 2.

Form Level Validation

In form-level validation, we pass the validation function into Form props and return the errors object per each field validation criteria. The error returned for a particular field then passes as a prop into a meta-object, and the user sees an error message.

import React from 'react'

import { render } from 'react-dom'

import Styles from './Styles'

import { Form, Field } from 'react-final-form'

const onSubmit = async values => {

  console.log(values)

}

const emailValid = (email)=> /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)

  

const passwordValid =(password) => "^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,10}$".test(password)

const handleValidate=(values)=>{

const errors ={}

 if(!emailValid(values.email)){

     errors.email = "Invalid Email"

  }

  if(!passwordValid(values.password)){

     errors.password = "Password must be 8 chars , at least one  number one letter"

  }

     return errors;

}

const App = () => (

 <Styles>

   <h1>React Final Form - Simple Example</h1>

   <Form

     onSubmit={onSubmit}

     initialValues={{ email: '', password :''}}

     validate={handleValidate}

     render={({ handleSubmit, form, submitting, pristine, values }) => (

       <form onSubmit={handleSubmit}>

        <Field name="email">

           {({ input, meta }) => (

             <div>

               <label>Email</label>

               <input {...input} type="text" placeholder="Email" />

               {meta.error && meta.touched && <span>{meta.error}</span>}

             </div>

           )}

         </Field>

         <Field name="password">

           {({ input, meta }) => (

             <div>

               <label>Password</label>

               <input {...input} type="password" placeholder="Password" />

               {meta.error && meta.touched && <span>{meta.error}</span>}

             </div>

           )}

         </Field>

         <div className="buttons">

           <button type="submit" disabled={submitting || pristine}>

             Submit

           </button>

           <button

             type="button"

             onClick={form.reset}

             disabled={submitting || pristine}

           >

             Reset

           </button>

         </div>

       </form>

     )}

   />

 </Styles>

)

render(<App />, document.getElementById('root'))

Field Level Validation

In field-level validation, we pass the validate function into Field components props and return the error message as per field validation criteria. The error returned for a particular field then passes as a prop into a meta-object, and the user sees an error message.

import React from "react";

import { render } from "react-dom";

import Styles from "./Styles";

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

const onSubmit = async (values) => {

 console.log(values);

};

const emailValid = (email) => {

 if (!/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/.test(email)) {

   return "Invalid Email";

 }

};

const passwordValid = (password) => {

 if (

   !"^(?=.*[a-z])(?=.*[A-Z])(?=.*d)(?=.*[@$!%*?&])[A-Za-zd@$!%*?&]{8,10}$".test(

     password

   )

 ) {

   return "Must contain minimum eight characters, at least one letter and one number:";

 }

};

const App = () => (

 <Styles>

   <h1>React Final Form - Simple Example</h1>

   <Form

     onSubmit={onSubmit}

     initialValues={{ email: "", password: "" }}

     render={({ handleSubmit, form, submitting, pristine, values }) => (

       <form onSubmit={handleSubmit}>

         <Field name="email" validate={emailValid}>

           {({ input, meta }) => (

             <div>

               <label>Email</label>

               <input {...input} type="text" placeholder="Email" />

               {meta.error && meta.touched && <span>{meta.error}</span>}

             </div>

           )}

         </Field>

         <Field name="password" validate={passwordValid}>

           {({ input, meta }) => (

             <div>

               <label>Password</label>

               <input {...input} type="password" placeholder="Password" />

               {meta.error && meta.touched && <span>{meta.error}</span>}

             </div>

           )}

         </Field>

         <div className="buttons">

           <button type="submit" disabled={submitting || pristine}>

             Submit

           </button>

           <button

             type="button"

             onClick={form.reset}

             disabled={submitting || pristine}

           >

             Reset

           </button>

         </div>

       </form>

     )}

   />

 </Styles>

);

render(<App />, document.getElementById("root"));

Advantages

  • Minimal Bundle Size
  • Simplicity
  • High Performance
  • Popularity and Community
coma

Conclusion

In this tutorial, we learned about React final form library, how we can use Final form components to handle the form submission and validations effectively.

Contact us today to hire a react.js developer who can help you implement it in your project and take your form game to the next level!

Keep Reading

Struggling with EHR integration? Learn about next-gen solutions in our upcoming webinar on Mar 6, at 11 AM EST.

Register Now

Let's create something together!