# React Controlled Components and Forms

## Controlling Form Values from State

* A controlled form is a form that derives its input values from state
    
* Consider the following form code
    

```javascript
import React, { useState } from "react";

function Form() {
  const [firstName, setFirstName] = useState("John");
  const [lastName, setLastName] = useState("Henry");

  return (
    <form>
      <input type="text" value={firstName} />
      <input type="text" value={lastName} />
      <button type="submit">Submit</button>
    </form>
  );
}

export default Form;
```

* Currently, the input values of the form will display what the state of firstName and lastName is set to
    
    * But there is no way to update the state yet.
        
* We can update the state by adding the onChange event listener as follows
    

```javascript
<input type="text" onChange={handleFirstNameChange} value={firstName}/>
<input type="text" onChange={handleLastNameChange} value={lastName} />
```

* With this, the onChange will execute every time the value of an input changes
    
* Below, find the functions to handle the changes, you will notice the functions take in an event as an argument, which is passed down from the onChange event listener
    

```javascript
function handleFirstNameChange(event) {
  setFirstName(event.target.value);
}
function handleLastNameChange(event) {
  setLastName(event.target.value);
}
```

## Form Element Types

* Form Elements:
    
    * &lt;input&gt;, &lt;textarea&gt;, &lt;select&gt;, and &lt;form&gt;
        
    * For these, the prop we use is **value**
        
    * For a checkbox &lt;input type="checkbox"&gt;, we used **checked,** which is a true or false value that can be set by the state through an onChange event listener
        

\*\*A major benefit of controlled forms is how it allows us to use the form values in other components

* You could have all the form states, logic, and functions stored in a parent component while passing down this logic as props to the Form component.
    
* As the state updates in the form, you can pass down the state to a different child component for other uses, such as displaying form inputs live as they're being typed.
    
    * This is very useful to capture user input and utilize it throughout your application, even if a server isn't involved.
        

## Form Validation with Controlled Forms

* Having controlled forms allows us the functionality to validate the input before setting the State for the input.
    
* For example, if you want the form to allow only numbers between 0 - 5, you can set up an if statement inside the call-back function for the onChange event listener as follows
    

```javascript
function handleNumberChange(event) {
    const newNumber = parseInt(event.target.value);
    if (newNumber >= 0 && newNumber <= 5) {
      setNumber(newNumber);
    }
  }
```

* If the input is invalid, we avoid setting the state and thus preventing the input from updating.
    
* As well, this allows us to set another state variable as an error that can be displayed if the input is not valid
    

## Submitting a Controlled Form

* When submitting the form, add an onSubmit event listener to the form element
    
    ```javascript
    return (
      <form onSubmit={handleSubmit}> //right here
        <input type="text" onChange={handleFirstNameChange} value={firstName} />
        <input type="text" onChange={handleLastNameChange} value={lastName} />
        <button type="submit">Submit</button>
      </form>
    );
    ```
    

Then create the callback function for handleSubmit as follows

```javascript
function handleSubmit(event) {
  event.preventDefault(); // need to do this like Javascript
  const formData = {    //Here we are adding the current State data at the
    firstName: firstName, //time of submit to an object variable
    lastName: lastName,
  };
  props.sendFormDataSomewhere(formData); //When submitted, this data should go somewhere
  setFirstName(""); //This is to clear the current input fields and reset the states
  setLastName("");
}
```

As well, in the handleSubmit call-back function, we can also validate the inputs for submission and send out error messages.

citations:

\-Flatiron School
