TIL - React Forms - controlled & uncontrolled components
Tags: react, beginners, forms, javascript
Published: 2020-09-01 15:25:31


#Summery
- A controlled component is a component where React is in control and is the single source of truth for the form data.
- An uncontrolled component is where your form data is handled by the DOM, instead of inside your React component.


## HTML Forms
When submitting a form, is made up of key-value pairs: 
```html 
<form>
 <label for='id'> </label>
 <input id='id' type='text' name='key' value='value'>
</form>
``` 

In HTML, the user can modify the field, regardless of whether the attribute value is set or not.

With React, the field can only be modified if no attribute value is given to it.

##Uncontrolled field
-> no value has been put on the input-field
```javascript
<form<
    <label htmlFor="character">Character:</label>
    <input
        id="character"
        name="character"
        type="text"
        onChange={(event) => {
           const input = event.target;
           console.log('NAME:', input.name, 'VALUE:',      
            input.value);
          }}
    />
 </form>
```
* use htmlFor instead of for on the `<label>` for is a reserved keyword in JavaScript.
* the use of onChange which allows to detect user input. It's the event listener associated with onChange which is responsible for the display you see in the console.
* event.target in the event listener of onChange is the element of the page on which the event occurred: the `<input>` field.
* The console displays the input's attributes: name (which does not change) and value (which varies as you type).
* Because there's no value attribute set on the character field, the value displayed in the field the one entered by the user.

```javascript
 const handleSubmit = (event) => {
    event.preventDefault();
    const firstName = event.target.firstName.value;
    const lastName = event.target.lastName.value;
    // Here we do something with form data
    console.log(firstName, lastName)
  }

 <form onSubmit={handleSubmit}>
        <label>
          Name:
          <input name="firstName" type="text" />
        </label>
        <label>
          Surname:
          <input name="lastName" type="text" />
        </label>
        <input type="submit" value="Submit" />
  </form>
``` 
The uncontrolled component above poses this problem: the value is not stored at the state level. 

##Controlled field

An `<input>` field is said to be controlled when the `<value>` of its value attribute is provided by the component that displays it: usually, this value comes from the state of the component.
Different from HTML: React controls the field's value via the value attribute.

1. You'll  have to change the name of the key to be initialized in the state.
2. In the render instead of a hardcoded value, set the input's value attribute using the value contained in the state.
3. Change the Value in the State: 
```javascript
const EssayForm = () => {
  
const [ value, setValue ] = useState(''); 

const handleChange =(event) => { setValue({event.target.value});  }
const handleSubmit= (event) => {
 alert('An essay was submitted: ' + value);
 event.preventDefault();
 }

  render() {
    return (
      <form onSubmit={handleSubmit}>
        <label>
          Essay:
          <textarea value={value} onChange={handleChange} />             
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}
```
## first steps 
{% codesandbox react-form-kkgse module=/MyTitleForm.js %}