Building forms in React


In this article, We will understand how to build forms in React.js

Building Forms are very common in any web application development. Unlike angular and angularJS, that gives form validation out of the box, we have to handle forms ourself in React. That includes complications like

  • How to get form values.
  • How to manage the form state.
  • How to validate the form on the fly.
  • How to show validation messages.

In HTML, form elements such as <input>, <textarea>, and <select> typically maintain their own state and update it based on user input.

In React, state of these input elements is typically kept in the state property of components and only updated with setState().

Controlled Component & Uncontrolled component

An input form element whose value is controlled by React in this way is called a “controlled input or Controlled Component”.

The alternative is uncontrolled inputs or components, where form data is handled by the DOM itself. We will use ref to get the input values and Perform Operations using this data.

We have discussed both of these ways of handling input changes in our previous sessions.

Though uncontrolled inputs are the simplest way to implement the form inputs they are not powerful enough to build our real-world applications. In this demonstration, we will use Controlled Inputs and definitely we all will understand the importance of them by the end of this Video.

To understand things in Practical lets open Index.js file. We will create a Class called EmployeeComponent and extend this from React Component.

Add a Constructor which accepts props as a parameter and pass it to the base class constructor

Let's create a state object, add a Property called as Id and initialize it to empty.

class EmployeeComponent extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      Id:''
  };
}

Now let's implement the render method

  • In render Method, we will create a form tag and lets place an input whose type is text.
  • Assign Id of the state object to value and onChange of the input value, let's call a function.
<form>
    <p>
        <label>Employee ID : <input type="text" name="Id"  value={this.state.Id}  onChange={this.changeHandler} ></input></label>
    </p>  
</form>

In the below function, we save the input text box value into our state object using the setState method. We can get the input value using e.target.value.

changeHandler = e => {
    this.setState({
      Id:e.target.value
    });
}

We will create another function called onCreateEmployee and log the Id value on to the console within this function.

onCreateEmployee=()=>{
    console.log(this.state.Id);    
  }

Let's place a button in our render method and call this function on click of this button.

<button onClick={this.onCreateEmployee}>Create</button>

Let's call this Employee Component, render this element to our root Container.

  • Save these changes, navigate to the browser and we can see that we have an input element in our page. Now enter some text into this textbox, click on the button and this value can be seen in the console window of the browser by using Developer Tools.
  • Now let's back to Visual studio code, Now we have to add more inputs for Name, Location and Salary.
  • In order to save these input values into our state object, let's add a new Employee object to our state and to this object, add Id, Name, Location and Salary as Properties.
this.state = {
      employee:{
      Id:'',
      Name:'',
      Location:'',
      Salary:''
      }
  };

Let's make the change for the input element value attribute so that it points to Id property of the employee Object.

Now we will add the input elements for Name, Location and Salary as well. 

<p>
    <label>Employee ID : <input type="text" name="Id" value={this.state.employee.Id} 
				onChange={this.changeHandler} ></input>
	</label>
</p>
<p>
	<label>Employee Name : <input type="text" name="Name" 
                                 value={this.state.employee.Name} 
                                onChange={this.changeHandler}></input>
	</label>
</p>
<p>
	<label>Employee Location : <input type="text" name="Location" 
                            value={this.state.employee.Location} 
                            onChange={this.changeHandler}></input>
	</label>
</p>
<p>
	<label>Employee Salary : <input type="text" name="Salary"
							value={this.state.employee.Salary} 
                            onChange={this.changeHandler}></input>
	</label>
</p>

If we observe this code, we are calling the same function for onChange event on every input element and it is the right way to do so. Because we cant create 20 functions if we have 20 inputs.

  • With this function, we have to handle the onChange event for all the inputs and update the state object using setState.

Let's get the input element Name using 

const name = event.target.name;

Get the value of that input using

const value = event.target.value;

Now we call setState method and we pass an employee object.

The employee object should contain all the previous property values. We get them using Spread Operator.

we should add a new Property to this employee object. Name of this property will be the input element name and this property will hold the value of that respective input element. We make a name as the property by writing it in the square brackets and assign the value.

this.setState({
      employee:{
        ...this.state.employee,
        [name]: value
      }
    });

Whenever User makes a change on any of the input elements, we are updating our state object using the setState method.

Within the onCreateEmployee function, lets log this employee object into the console.

Save these changes, navigate to the browser.

Enter the data into these inputs, click on the create button and we can see that employee object details are logged into the Console window.

Now we have understood how to create a simple form. 

But to this form we want to add validations, we want to keep track of the visited fields, and we have to handle form submission,

Formik is one of the popular library available and let's use this library for building powerful forms in our react application.

Formik is a small group of React components and hooks for building forms in React and React Native. It helps with the three most parts:

  1. Getting values in and out of form state
  2. Validation and error messages
  3. Handling form submission

Let's navigate to our node js command prompt. Run a command to install formik into our project.

npm install formik –save

After the installation is successful, run our project using 

Npm start 

Let's switch back to Visual studio code, let's delete all the code we have written.

Lets import use Formik from formic.

Let's create EmployeeComponent class and extend it from React. Component class.

class NewEmployeeComponent extends React.Component {
}

Let's implement the render method

Let's call useFormik function, pass an object which contains initial values for Id, Name, Location and Salary.

And also pass a onSubmit function () to the useFormik(). In this function, we will display the forms of current values using an alert.

Let's return the div container in which we will place our form tag.lets pass formik. handleSubmit to the onSubmit attribute of the forms.

<form onSubmit={formik.handleSubmit}>

Let's place input elements for Id, Name, Location and Salary.

To that input element onChange event, we will pass handleChange function of formik object and we will bind the value from the formik object as well.

<p>
    <label htmlFor="Id">Employee ID </label>
    <input
        id="Id"
        name="Id"
        type="text"
        onChange={formik.handleChange}
        value={formik.values.Id}
    />
</p>

Let's repeat the same for the rest of the input elements.

Let's add a button with in the form.

Let's Call this Component and render it to our root container.

Save these changes and let's navigate to the browser. Enter the Employee details and let's click on Create Button. 

We can see that employee data is displayed in the alert as a JSON object. We can pass this data to our Web API as we have discussed in our Last Video.

If we look at the code what we have written, 

We pass our form's initialValues and a submission function (onSubmit) to the useFormik() function. The function then returns us an object using which we will access 

handleSubmit which is A submission handler

handleChange which is A change handler to pass to each <input>, <select>, or <textarea>

values: using which we access Our form's current values.

import React from 'react';
import ReactDOM from 'react-dom';
import { useFormik } from 'formik';

class NewEmployeeComponent extends React.Component {
  render(){
  const formik = useFormik({
    initialValues: {
      Id: '',
      Name: '',
      Location: '',
      Salary:''
    },
    onSubmit: values => {
      alert(JSON.stringify(values));
    },
  });
  return (
    <div>
    <h2>Enter Employee Details...</h2>
    <form onSubmit={formik.handleSubmit}>
      <p>
      <label htmlFor="Id">Employee ID </label>
      <input
        id="Id"
        name="Id"
        type="text"
        onChange={formik.handleChange}
        value={formik.values.Id}
      />
      </p>
      
      <p>
      <label htmlFor="Name">Employee Name </label>
      <input
        id="Name"
        name="Name"
        type="text"
        onChange={formik.handleChange}
        value={formik.values.Name}
      />
      </p>
      <p>
      <label htmlFor="Location">Employee Location </label>
      <input
        id="Location"
        name="Location"
        type="text"
        onChange={formik.handleChange}
        value={formik.values.Location}
      />
      </p>
      <p>
      <label htmlFor="Salary">Employee Salary </label>
      <input
        id="Salary"
        name="Salary"
        type="text"
        onChange={formik.handleChange}
        value={formik.values.Salary}
      />
      </p>
      <button type="submit">Submit</button>
    </form>
    </div>
  );
  }
};

const element=<NewEmployeeForm></NewEmployeeForm>

ReactDOM.render(element,document.getElementById("root"));

Video Reference:





© 2020 Pragimtech. All Rights Reserved.