DEV Community

loading...
Cover image for How to create dynamic forms in react using react-hook-forms.

How to create dynamic forms in react using react-hook-forms.

vineetpardhi profile image Vineet Pardhi ・4 min read

Hi guys,

If you are a React Developer you might know that Creating forms in Reactjs is quite easy, yet you need to adjust your code with a lot of things. I am going to write about a few things that you need to know while creating dynamic forms and also explain how they are written.

Why Dynamic Forms?

  • These days, most of the big tech companies like Google, Amazon, Netflix use dynamic forms in their front-end applications since they have to handle massive scale of data and dynamic forms help to create forms that receive the schema in form of the API data, so that we don't have to worry about the fields which we are going to set in our code.
  • Another reason why most of the large scale applications should use dynamic forms is that the Dynamic form component we build can be a reusable component for other components as well. which have a probability to reduce the half of our code.

The libraries that can be used to create dynamic forms.

There are many Libraries to create Dynamic Forms in react like react-jsonchema-form, Formik, react-form, react final-form most of these the libraries are used immensely, but I would suggest you to use react-hook-forms because of some reasons given below.

  • Almost zero dependencies.
  • Very low latencies.
  • Less code, since it consists of hook functions.

Let's Get Started

To install react-hook-form in your application copy the line below

npm install react-hook-form
Enter fullscreen mode Exit fullscreen mode

To view better UI try to install dependencies like react-strap/bootstrap/material, I am going to use react-strap in the example below.

To use react-hook-form follow the code below.

import {useForm} from 'react-hook-form';
import {Card, CardBody, Form, Row, Button} from 'reactstrap';

const MainComponent=(props)=>{
let {register, handleSubmit, errors}=useForm();
}
Enter fullscreen mode Exit fullscreen mode
Creating a JSON form in Javascript

Create a component which returns a template to map the fields in the Form which we are going to create. Let's take a Basic example of Employee, you can create according to your components.


import React from 'react';

export const template = {
    title: 'Basic Form to Add Employee',
    Fields: [
        {
            name:'firstName' ,
            type:'text',
            title:'First Name',
            required:{
                value:true,
                message:'Employee First Name is required'
            },
            validation:function(val){
                return val.length >=5 || 'Min Length is 5';
            }
        },
        {
            name:'lastName' ,
            type:'text',
            title:'Last Name',
            required:{
                value:true,
                message:'Employee Last Name is required'
            },
            validation:function(val){
                return val.length >=5 || 'Min Length is 5';
            }
        },
    ]
};

Enter fullscreen mode Exit fullscreen mode

you can search and refer to JSON forms available on net. so that you can learn more about the schema and create different types of fields for template.

Creating a CustomForm component to render the template.

we create a function/method to renderfields and return the call the method while returning the component.


import React from 'react';
import {Input, Label, FormGroup, FormText, FormFeedback, Row, Col} from 'reactstrap';



//for a select input type
const renderOptions=(options)=>{
    return options.map((child)=>{
        return(
            <option key={child.value} value={child.value}>{child.label}</option>
        );
    });
};





function CustomForm({ template, data, handleform}) {
let {register,errors} = handleform;
const renderFields = (fields) => {

        return fields.map(field => {
            let { type, title, name, required,validation} = field;


switch(type){
      case 'text':
    return (
        <FormGroup key={name}>
         <Label htmlFor={name}>
                  {title}
                  <span style={required?{color:'red'}:{}}>*</span> 
                 </Label>
                 <Input             
                  type='text'
                  name={name}                        
                  innerRef= 
               {register({required:required,validate:validation})}
                  />                             
                  {errors[name] && 
                  <FormFeedback>
                   {errors[name].message} 
                 </FormFeedback>}                   
              </FormGroup>
    );

     case 'select':
    let {options}=field;
    return (
      <FormGroup key={name}>
        <Label htmlFor={name}>{title}<span style={required?{color:'red'}:{}}>*</span></Label>
        <Input  
             type='select' 
             name={name} 
             innerRef={register}
        >

            {renderOptions(options)}
        </Input>
          </FormGroup>
    );

      default:
       return (
        <div>
          <span>Invalid Field</span>
               </div>
    );
      }
   });

};
let { title, Fields } = template;
    return (
        <>
            <h4>{title}</h4>
            <Row>
                <Col>
                    {renderFields(Fields)}
                </Col>
            </Row>
        </>

    );

}

Enter fullscreen mode Exit fullscreen mode

You can handle different types of cases and render the fields according to it.

Rendering CustomForm component using react-hook-form

useForm() returns Field elements to handle form in its own way.

  • register method allows you to register an input/select Ref and apply validation rules into React Hook Form.

  • handleSubmit function will pass the form data when form validation is successful and can be invoked remotely as well.

  • errors is an Object containing form errors and error messages corresponding to each field.

You can read more about this in the documentation

So, create a return element in the App component or in whatever component in which you are going to render the form.


let handleform={
   register:register,
   errors:errors
};
return(
<Card>
 <CardBody>
  <Form onSubmit={handleSubmit(onSubmit)}>                  
   <Row className="d-flex justify-content-end">                     
     <Button                             
        type='submit'                            
        className="mt-0 mr-1"                            
        color="primary">                    
        Save Changes                        
      </Button>
      <CustomForm  
        template={template} 
        handleform={handleform}
       />
  </Form>
 </CardBody>
</Card>)

Enter fullscreen mode Exit fullscreen mode

you can pass the state to props in the Custom Form which have built earlier.

Conclusion

This way you can render dynamic Forms in reactjs using react-hook-form and also it helps you with your form validation, schema and rendering.

If you like this article, share it with you dev community or with your geek folks.

Thanks.

Discussion (6)

pic
Editor guide
Collapse
pozda profile image
Ivan Pozderac

Great article!
I also prefer react-hook-form over every other form library.

I am currently working on dynamic form generation from passed object that has validation included so everything is fully customizable, this is similar approach.

Collapse
fmsthird profile image
fmsthird

have you tried Formik?

Collapse
pozda profile image
Ivan Pozderac

Yep. I tried react-hook-form after I worked with Formik and I found it to be more simple to use in general. They got me with simplicity of use and minimal re-rendering.

Thread Thread
fmsthird profile image
fmsthird

That's interesting. I am a newbie to React, and since then, I am using Formik. I might try react-hook for my next project.

Collapse
rahulsolankib profile image
rahulsolankib

Great explanation! Waiting for more such articles

Collapse
vineetpardhi profile image