React Event Handling
Tags: beginners, react, webdev, javascript
Published: 2023-06-19 10:02:45

Hello there! 👋 We are going to learn about React Event handling today.

We know about the html event handling with Html and JavaScript. React does this event handling in a similar but kind of different way. We are going to deep dive on it today. 😁

## Difference between HTML and React Events

First let's see how we do it in HTML and JavaScript. We created a simple button with a click event and once the button is clicked it will show in the browser console.

```
<button onclick="handleClick()">Click</button>

<script>
  function handleClick() {
    console.log("You have clicked the event");
  }
</script>
```

![Button click event](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bjzsa8o1n81vssk955zw.gif)

We will do the same thing for React now. We will use our previous code for state and will remove the props `locale` we passed from the `App` to `Clock` component.

```
function App() {
  return (
    <Clock />
  )
}
```
We will change the `Clock` locale based on the click event now. 💪🤗

Now let's create a button in React. 🎉🎊😁 
Let's open our `Clock` component and update in the `render` method.
```
  render() {
    const { date } = this.state;
    return (
      <div>
        <h1 className="heading">
          <span>Hello <span>{this.props.children}</span> { date.toLocaleTimeString('en-US')}</span>
        </h1>
        <button>Click here</button>
      </div>
    );
  }
```

![React Button](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7ril763ho84s5ml7mkf5.gif)

We can see that we have added a button. But the button isn't functional yet. So there is no event handling there yet. Let's work on it and find out the differences with html button click events. 😊

```
<button onClick={}>Click here</button>
```
We are adding an `onClick` event on the React button. Now let's see our html button `onclick` event.
```
<button onclick="handleClick()">Click</button>
```
Here we can clearly see that we are calling a string `"handleClick()"` not the function `handleClick()` on the html button click.

So why are calling a string?

This is because of not calling the `handleClick()` function when the page is loaded. But the `handleClick()` function will only be called when we click the button. Because that time the `onclick` event will trigger the `handleClick()` function.

Note that, in case of `React` events we need to write **camelcase** event. Like we are using `onClick` for `React` not `onclick` like we used for html events.

Also we are not calling string in React. We will call functions inside the curly braces `onClick={}`. Now let's create a `handleClick` function inside our `Clock` class component.
```
handleClick() {
  console.log("The button is clicked");
}
```
And in our onClick event let's call the `handleClick` function.
```
<button onClick={this.handleClick}>Click here</button>
```

We are using `this.handleClick` because it is inside the `Clock` class component. As the `handleClick` method is inside the class component we have to use `this` to call that method.

But we found another difference with the html event call with React. Look below codes

**HTML** => `onclick="handleClick()"`
**React** => `onClick={this.handleClick}`

In React we are not calling the handleClick function like HTML.

The reason is in HTML we are actually calling string but in React we are not calling the string.

So, in the case of React we directly call the `handleClick` function. It will actually call during page load. Not during the click event. 🤔

Let's go to the browser now and check.

![Updated Click Event](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o8bg25chdxbb74km372d.gif)

So we can see that the `handleClick` function is working and the log message is showing.

## Handling Default behavior

Let's think about a html link. It has a default behavior to go to the link provided. Let's see an example.
```
<a href="test.html">Click this</a>
```
We can see here that this is a link and when we click it will go to the `test.html` url. We can change this default behavior using `return false;` with the `onclick` event.
```
<a href="test.html" onclick="console.log('You have clicked the event'); return false;">Click here</a>
```
After updating we can see that this is no longer going to the url and we can see the log message `Link is clicked` in the console.

But in React we can not use `return false;` to prevent the default behavior inside DOM.

We can also prevent the default behavior using the `preventDefault` function when the event will be passed as parameter in JavaScript. And we can use this technique in React events also to prevent default behavior.

Let's go to our React project now. We can see that we have called the `this.handleClick` function. This `handleClick` function will actually get the event as a parameter. So we can write this function as `handleClick(e)` here `e` is the event. And then we will call the `e.preventDefault() `function to prevent the default behavior of that event.
```
  handleClick(e) {
    e.preventDefault();
  }
```
Now even if we change the button to link or submit button the default behavior will be prevented and we will only see what is inside the handleClick function.
```
<a type="button" href="test.html" onClick={this.handleClick}>Click here</a>

<button type="submit" onClick={this.handleClick}>Click here</button>
```

## Update locale using React state and click event

Now, let's update the functionality of the handleClick function so that it can change the locale of the Clock when we click the button.

Let's first create a React state `locale` and set default to `bn-BD`. And update in our render function.
```
state = {date: new Date(), locale: 'bn-BD'}

render() {
  const { date, locale } = this.state;
  return (
    <div>
      <h1 className="heading">
        <span>Hello <span>{this.props.children}</span> { date.toLocaleTimeString(locale)}</span>
      </h1>
      <button type="submit" onClick={this.handleClick}>Click here</button>
    </div>
  );
}
```
We have changed to `date.toLocaleTimeString(locale)` from `date.toLocaleTimeString('en-US')`.

And now let's update in our `handleClick` function and check in the browser.
```
  handleClick(e) {
    e.preventDefault();
    this.setState({
      locale: 'en-US'
    });
  }
```

![handleClick setState](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hfukjtlw3jcvdouwn4pp.png)

Oh no! We got an error! 😭😱 It is saying `Uncaught TypeError: Cannot read properties of undefined (reading 'setState')`
But this didn't happen in our tick method. Why is it happening here? Let's find out.

So here the problem is we are getting `this` as `undefined`. Why is that?

Actually, here we are using the `Clock` component which is a class component. We might know that class is a blueprint of the object. So here we have `this` which is the object of the `Clock` class. By using `this` we can access all the properties of the `Clock` class.

So here in the `render` method when we use `this.handleClick` it is calling the handleClick method without any issues. But inside the `handleClick` method this isn't passed, just the reference is passed.

So what happens here is, After the click event this isn't instantly calling the `handleClick` function. Here it is just a callback function.

When the callback function is called, it can't find `this` that time. That's why we are getting `this` as `undefined`.

## Fixing `this` issue

There are several ways to fix the `this` issue in the class component. Let's try to fix it now. 🎉🥳

**1. Making handleClick method as arrow function.**

Let's update our handleClick method to an arrow function.
```
 handleClick = (e) => {
    e.preventDefault();
    this.setState({
      locale: 'en-US'
    });
  }
```
We can do a `console.log(this)` inside the handleClick method to check `this`.

![Arrow function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pn96ih8o69h3sika3w88.png)

We can see that there is no error and we have successfully updated the state of `locale` to "en-US".

The reason why the arrow function works but the traditional function not working is because the arrow function doesn't use additional scope for it. So it didn't change `this` inside the function. Where our normal function has its own scope, so we couldn't access `this` inside our normal function.

This is one of the main reasons we use arrow functions in such cases.

**2. Using `bind`**

If we don't want to use the arrow function (although that is recommended) we can use `bind` to use `this` inside the `handleClick` function.

We need to create a constructor function and update it there.
```
constructor(props) {
    super(props);
    this.state = {date: new Date(), locale: 'bn-BD'}
    this.handleClick = this.handleClick.bind(this);
  }
```

And keep the onClick event function same as before.
```
onClick={this.handleClick}
```
So that's it!

We are doing the same thing inside the constructor. The bind method binds our object inside the `handleClick` method so we can access it inside the `handleClick` method.

So in the constructor we are telling that the `this.handleClick` is not the full function. `this.handleClick` means `this.handleClick.bind(this)` function where we are binding this and passing to `handleClick` function. 

**3. Passing Parameters to handleClick function**
In this case we actually need to update where we are calling the function in the onClick event. We can actually do this. Instead of adding a constructor.

```
onClick={this.handleClick.bind(this)}
```

Also we can pass parameters from this onClick event.
```
onClick={this.handleClick.bind(this, 'en-US')}
```
By using this bind we can easily pass the parameters.
So the handleClick method can be updated to
```
handleClick(locale) {
    this.setState({
      locale
    });
  }
```
Easy right! 😁🤗

![React Event Handling](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5c9uwqtw3e6dqh4lypeh.jpg)

Also there is another way if we want to use arrow function on the onClick event. 

```
onClick= {() => this.handleClick('en-US')}
```

![Arrow function on onclick event](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1erxwaywvg7vne9pu1sc.jpg)

This one is more easier! yay! 😁😄 

That's all about event handling in React today. Thank you for reading. 🙏😊 

Here is the [github repository](https://github.com/rabibsust/react/tree/master/handling_events) for todays code.

I might come out tomorrow with some new topics. Till then goodbye! 👋🙏🙌