React Form Handling

Adding Forms

Forms in React are written in the same way as in HTML. Forms maintain an internal state naturally. All forms of data should be stored in a state.

Example of a form in React:

import React, { Component } from "react";
import ReactDOM from 'react-dom'

class NewForm extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    return (
      <form>
        <p>Enter your name: </p>
        <input type="text" name="firstName" />
        <input type="submit" />
      </form>
    );
  }
}

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

Result :

Handling Forms

Handling forms in HTML is done by the DOM, in React form data is handled internally by the components, the data are stored in state. Most form data in React are handled by the onChange attribute:

import ReactDOM from "react-dom";

class NewForm extends Component {
  constructor() {
    super();
    this.state = { firstName: "" };
  }
  formHandler = (event) => {
    this.setState({ firstName: event.target.value });
  };
  render() {
    return (
      <form>
        <p>Enter your name: {this.state.firstName} </p>
        <input type="text" onChange={this.formHandler} name="firstName" />
        <input type="submit" />
      </form>
    );
  }
}

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

Result :

Add an event handler in the onChange attribute called ‘formHandler’ which handles update on the state object. You can have access to the input value by using event.target.value object.

Submitting Forms

Submitting forms in React is done by adding an onSubmit attribute to the form tag and assigning an event handler:

import React, { Component } from "react";
import ReactDOM from "react-dom";

class NewForm extends Component {
  constructor(props) {
    super(props);
    this.state = { firstName: "" };
  }
  formHandler = (event) => {
    this.setState({ firstName: event.target.value });
  };
  submitHandler = (event) => {
    event.preventDefault();
    window.alert("You submitted " + this.state.firstName);
  };

  render() {
    return (
      <form onSubmit={this.submitHandler}>
        <p>Enter your name: {this.state.firstName} </p>
        <input onChange={this.formHandler} type="text" name="firstName" />
        <input onChange={this.formHandler} type="submit" />
      </form>
    );
  }
}

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

The event.preventDefault() prevents the default action of the page loading or actually submitting the form.

Multiple Input Handling

When you create a component state use the name attribute of the input fields as object keys. To access values of multiple field types use the name attribute, ‘event.target.name’ and ‘event.target.valuesyntax.

import React, { Component } from "react";
import ReactDOM from "react-dom";

class NewForm extends Component {
  constructor(props) {
    super(props);
    this.state = { firstName: "", lastName: "" };
  }

  formHandler = (event) => {
    let name = event.target.name;
    let value = event.target.value;
    this.setState({ [name]: value });
  };
  submitHandler = (event) => {
    event.preventDefault();
    window.alert("You submitted" + this.state.firstName + this.state.lastName);
  };
  render() {
    return (
      <form onSubmit={this.submitHandler}>
        <p>
          Enter your name: {this.state.firstName}, {this.state.lastName}
        </p>
        <input type="text" onChange={this.formHandler} name="firstName" /><br />
        <input type="text" onChange={this.formHandler} name="lastName" /><br />
        <input type="submit" />
      </form>
    );
  }
}
ReactDOM.render(<NewForm />, document.getElementById("root"));

Bracket notation, [] is used around the property name.

Handling checkboxes

 Let’s now go through a special form field called a checkbox. The checkbox does not have a value attribute instead it states is determined by a Boolean value of being false(not checked) or true(checked). If the checked attribute is true the checkbox is checked.

import React, { Component } from "react";
import ReactDOM from "react-dom";

class NewForm extends Component {
  constructor(props) {
    super(props);
    this.state = { firstName: "", lastName: "", canDrive: true };
  }
  formHandler = (event) => {
    let name = event.target.name;
    let value = event.target.value;
    this.setState({ [name]: value });
  };
  submitHandler = (event) => {
    event.preventDefault();
    window.alert("You submitted " + this.state.firstName + this.state.lastName);
  };
  render() {
    return (
      <form onSubmit={this.submitHandler}>
        <p>
          Enter your name: {this.state.firstName}, {this.state.lastName}
        </p>
        <input type="text" onChange={this.formHandler} name="firstName" />{" "}
        <br />
        <input type="text" onChange={this.formHandler} name="lastName" />
        <br />
        <input
          type="checkbox"
          onChange={this.formHandler}
          checked={this.state.canDrive}
        />{" "}
        Can you drive?
        <input type="submit" />
      </form>
    );
  }
}
ReactDOM.render(<NewForm />, document.getElementById("root"));

We initialized the state of the checkbox to be true, this makes this input field to be read-only, that is, it can be changed from checked to unchecked. Try it. To take care of this problem, we have to let React know that this input field type is a checkbox, we use conditional rendering to achieve this:

import React, { Component } from "react";
import ReactDOM from "react-dom";

class NewForm extends Component {
  constructor(props) {
    super(props);
    this.state = { firstName: "", lastName: "", canDrive: true };
    this.formHandler = this.formHandler.bind(this)
  }
  formHandler = (event) => {
   const [name, type, checked, value] = event.target
    type === "checkbox"
      ? this.setState({[name] : checked})
      : this.setState({ [name]: value });
  };

  submitHandler = (event) => {
    event.preventDefault();
    
  };
  render() {
    return (
      <form onSubmit={this.submitHandler}>
        <p>
          Enter your name: {this.state.firstName}, {this.state.lastName}
        </p>
        <input type="text" onChange={this.formHandler} name="firstName" />{" "}
        <br />
        <input type="text" onChange={this.formHandler} name="lastName" />
        <br />
        <input
          type="checkbox"
          onChange={this.formHandler}
          checked={this.state.canDrive}
          name="canDrive"
        />
        Can you drive?
        <input type="submit" />
      </form>
    );
  }
}
ReactDOM.render(<NewForm />, document.getElementById("root"));

Now we tell react that if the input field type is a checkbox, assign the name property to ‘event.target.checked else assign to ‘event.target.value’.

Notice the bracket notation that makes our code look neater.

Handling forms in React can be exhausting and prone to risks and bugs, so we can use a React form add-on called Formik to handle all our form data. It is very light-weight and neater.