Learn React - Part 4 - Events and forms
Tags: react, javascript, webdev
Published: 2019-01-29 08:58:23

---
title: Learn React - Part 4 - Events and forms
published: true
description: Learn React - how to answer to events, create forms and manipulate them
tags: react, reactjs, javascript, web development
canonical_url: https://felipegalvao.com.br/blog/2019/01/27/learn-react-events-and-forms/
series: Learn React
---

[Originally published in my blog](http://felipegalvao.com.br/blog/2019/01/27/learn-react-events-and-forms/)

Hey folks. In our [last post](https://dev.to/felipegalvao/learn-react---part-3---components-state-and-props-1h0g), we talked about **components, state and props**. In this one, we will talk about **events and forms**. These two are vital subjects for any web app, and despite not being really difficult in React, they present certain particularities.

Let's start with the same boilerplate that we have been using in all of our previous posts about React. You can find it here: https://github.com/felipegalvao/webpack-4-react-boilerplate

Let's go!

## Events

First of all, what are events? Events are used to notify your code that something interesting is happening. This interesting thing can be triggered by the user or by the page itself. For example, a user clicks on a button, or a page finished loading, or the value of a text input changes.

With that out of the way, we can continue. In **React**, events are kinda similar to basic **HTML + Javascript**, but with some differences. Let's see the example for the `onClick` event. While in HTML we would do:

```html
<button href="#" onclick="alert('row was added!');">
  Add row
</button>
```html

In React, we have our code inside of curly braces, and it would look like that (with the code for the component):

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

import './styles/main.scss';

class Index extends Component {
  render() {
    return <div>
      <button onClick={ () => alert('row was added!') }>add row</button>
    </div>;
  }
};

ReactDOM.render(<Index />, document.getElementById("index"));
```

In React, to run the Javascript code directly within the event, we have to use an **arrow function** and have the code in this way, so that the code won't run when the component is rendered. It is also possible to call a predefined function. In HTML, we would do this:

```html
<button onclick="handleClick()">
  add row
</button>
```

In React, we will put the function inside the curly braces. As we already saw in the [post about state and props](https://dev.to/felipegalvao/learn-react---part-3---components-state-and-props-1h0g), for the `this` keyword to work, we need to `bind` it in the component's `constructor`:

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

import './styles/main.scss';

class Index extends Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    alert('row was added!');
  }

  render() {
    return <div>
      <button onClick={ this.handleClick }>add row</button>
    </div>;
  }
};

ReactDOM.render(<Index />, document.getElementById("index"));
```

If this bothers you, there are two other ways to make it work, as explained on the same post. I, particularly, prefere arrow functions to handle this type of problem.

Well, after writing the code above, you can click on the button and you will get the browser alert. `onClick` is the most common event for buttons.

Another event that is really common is the `onChange` event, mostly used with the input element. The `onChange` event is triggered every time the value of the input changes. Let's see that behavior using the code below:

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

import './styles/main.scss';

class Index extends Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
    this.handleTextChange = this.handleTextChange.bind(this);
    this.state = {currentText: ''}
  }

  handleClick() {
    alert('row was added!');
  }

  handleTextChange(event) {
    this.setState({currentText: event.target.value});
  }

  render() {
    return <div>
      <button onClick={ this.handleClick }>add row</button>
      <input
        type="text"
        placeholder="enter your name here"
        onChange={ this.handleTextChange }
      />
      <p>{ this.state.currentText }</p>
    </div>;
  }
};

ReactDOM.render(<Index />, document.getElementById("index"));
```

Start typing on the text input and see how the paragraph will change accordingly. Note that, in this case, we have to set a initial state with an empty string. If we don't do this, the paragraph will break when trying to render, as the part of the state that we will try to reference will not be defined.

## Forms - controlled components

Having learned about events, let's now talk about forms. Forms, as we already talked about, are a huge part of a great number of web apps, and because of that, it's important to understand how they work on React.

In React, recommended way to work with forms is through the concept called **controlled components**. In this way of working, we make so that the state is the **single source of truth** for the values in the form, and we use the events on the elements of the form to keep updating the values on the state. And then you call the function to submit the form on the **onSubmit** event for the form. For a simple form, with a text input, it would be like this:

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

import './styles/main.scss';

class Index extends Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleTextChange = this.handleTextChange.bind(this);
    this.state = {name: ''}
  }

  handleSubmit(event) {
    alert('Your name was sent to our API, ' + this.state.name);
    event.preventDefault();
  }

  handleTextChange(event) {
    this.setState({name: event.target.value});
  }

  render() {
    return <div>
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input
            type="text"
            placeholder="enter your name here"
            onChange={ this.handleTextChange }
            value={ this.state.currentText }
          />
        </label>
        <input type="submit" value="Send" />
      </form>
    </div>;
  }
};

ReactDOM.render(<Index />, document.getElementById("index"));
```

Type your name and then click on the `Send` button, and you will see the alert with the name you typed in the input. Let's add a `select` element:

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

import './styles/main.scss';

class Index extends Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleTextChange = this.handleTextChange.bind(this);
    this.handleColorSelect = this.handleColorSelect.bind(this);
    this.state = {name: '', favoriteColor: 'blue'}
  }

  handleSubmit(event) {
    alert(
      `Your name is ${this.state.name} and your favorite color is ${this.state.favoriteColor}`
    );
    event.preventDefault();
  }

  handleTextChange(event) {
    this.setState({name: event.target.value});
  }

  handleColorSelect(event) {
    this.setState({favoriteColor: event.target.value});
  }

  render() {
    return <div>
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input
            type="text"
            placeholder="enter your name here"
            onChange={ this.handleTextChange }
            value={ this.state.currentText }
          />
        </label>
        <select value={this.state.favoriteColor} onChange={this.handleColorSelect}>
          <option value="blue">Blue</option>
          <option value="red">Red</option>
          <option value="green">Green</option>
          <option value="black">Black</option>
        </select>
        <input type="submit" value="Send" />
      </form>
    </div>;
  }
};

ReactDOM.render(<Index />, document.getElementById("index"));
```

For the `select` element, you create each option inside of the element with its own value, and then you pass the event to the function to be called when the select element value is changed. Go on and test it, selecting your favorite color and clicking on the button to submit the form.

To finish this post, let's see how `radio` buttons work in React. It's pretty similar to the `select` element. I'll add some `div` to better organize the code and the layout, and then I'll add the `radio` buttons:

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

import './styles/main.scss';

class Index extends Component {
  constructor(props) {
    super(props);
    this.handleSubmit = this.handleSubmit.bind(this);
    this.handleTextChange = this.handleTextChange.bind(this);
    this.handleColorSelect = this.handleColorSelect.bind(this);
    this.handleAnimalSelect = this.handleAnimalSelect.bind(this);
    this.state = {name: '', favoriteColor: 'blue', favoriteAnimal: ''}
  }

  handleSubmit(event) {
    alert(
      `Your name is ${this.state.name}, your favorite color is ${this.state.favoriteColor}` +
      `and your favorite animal is ${this.state.favoriteAnimal}`
    );
    event.preventDefault();
  }

  handleTextChange(event) {
    this.setState({name: event.target.value});
  }

  handleColorSelect(event) {
    this.setState({favoriteColor: event.target.value});
  }

  handleAnimalSelect(event) {
    this.setState({favoriteAnimal: event.target.value});
  }

  render() {
    return <div>
      <p>Insert your name, your favorite color and your favorite animal.</p>
      <form onSubmit={this.handleSubmit}>
        <div>
          <label>
            Name:
            <input
              type="text"
              placeholder="enter your name here"
              onChange={ this.handleTextChange }
              value={ this.state.currentText }
            />
          </label>
        </div>
        <div>
          <select value={this.state.favoriteColor} onChange={this.handleColorSelect}>
            <option value="blue">Blue</option>
            <option value="red">Red</option>
            <option value="green">Green</option>
            <option value="black">Black</option>
          </select>
        </div>
        <div>
          <label>
            <input
              type="radio"
              name="react-tips"
              value="dog"
              checked={this.state.favoriteAnimal === "dog"}
              onChange={this.handleAnimalSelect}
            />
            Dog
          </label>
        </div>
        <div>
          <label>
            <input
              type="radio"
              name="react-tips"
              value="cat"
              checked={this.state.favoriteAnimal === "cat"}
              onChange={this.handleAnimalSelect}
            />
            Cat
          </label>
        </div>
        <div>
          <input type="submit" value="Send" />
        </div>
      </form>
    </div>
  }
};

ReactDOM.render(<Index />, document.getElementById("index"));
```

Note that, for the `radio` buttons, we define if it's `checked` or not by comparing it's value with the value that is currently in the state.

And with this, we were able to learn how to work with forms in React, and also how to use the most common form elements.

In "real life" examples, the submit of a form would probably make a request to an API with its values, possibly using Axios, fetch or any other way you prefer. But this is a subject for another post.

Cheers and I hope this is helpful.