Table of Contents
Event Handling in React
What we have learned so far?
Part 1 – Hello Word in React?
https://onlyfullstack.blogspot.com/2019/11/create-reactjs-app-hello-world.html
Part 2 – JSX in React
https://onlyfullstack.blogspot.com/2019/11/jsx-in-react.html
https://onlyfullstack.blogspot.com/2019/11/react-components-state-props-lifecycle.html
Handling events with React elements is very similar to handling events on DOM elements. There are some syntactic differences:
- React events are named using camelCase, rather than lowercase.
- With JSX you pass a function as the event handler, rather than a string.
For example, the HTML:
<button onclick="handleSimpleEvent()">Simple Event Handler</button>
In React you can write as below :
<button onClick={this.handleSimpleEvent}>Simple Event Handler</button>
Lets see how we can do the event handling in React. We will design below screen where each button will have some events associated with it.
Simple Event Handler – Here we will implement simple event handling and we will just show an alert message
Hide Counter / Show Counter – This will show or hide the counter div.
Increment – This will increment the counter
Decrement – This will decrement the counter
So, Lets start
import React, { Component } from "react"; import { render } from "react-dom"; import Hello from "./Hello"; import "./style.css"; class App extends Component { handleSimpleEvent() { alert("Inside handleSimpleEvent"); } render() { return ( <div> <p>Event Handler</p> <button onClick={this.handleSimpleEvent}>Simple Event Handler</button> </div> ); } }
Here we have created a new button and added onClick event to it and that’s it.
Why does onClick is not having a method parentheses?
<button onClick={this.handleSimpleEvent()}>Simple Event Handler</button>
As you know, we write the HTMLs inside the render function so where the page renders, Dom thinks that it has to call that function while rendering so it will directly call that function for the first time. Its basic JavaScript. Lets take an example to understand it in a better way.
Q.1) How to call the function that we have defined?
Ans: a();
Q.2) How to pass reference of function so that we can call it latter?
Ans: let fun = a;
Now coming to your question, you have used paranthesis with function name, mean that function will be called and will show an alert when following statement will be render. So never give parenthesis in react events.
Lets do more with event handling and we will implement the counter.
import React, { Component } from "react"; import { render } from "react-dom"; import Hello from "./Hello"; import "./style.css"; class App extends Component { constructor(props) { super(props); this.state = { counter: 0, // Initiate state of the counter }; this.handleIncrement = this.handleIncrement.bind(this); this.handleDecrement = this.handleDecrement.bind(this); } handleIncrement() { this.setState({ counter: this.state.counter + 1 }); } handleDecrement() { this.setState({ counter: this.state.counter - 1 }); } render() { return ( <div> <div> <p>Event Handler</p> <div> <button onClick={this.handleIncrement}>Increment</button> <button onClick={this.handleDecrement}>Decrement</button> <p>Current Counter : {this.state.counter}</p> </div> </div> </div> ); } }
Here we have added 2 button and gave 2 different methods to increment and decrement the counter.
Why do we need to bind event handlers in React?
Wait, What extra piece of code is added in constructor? Why do we need to bind the methods in constructor now? We haven’t done this in Simple Event Handler example.
When you call {this.handleIncrement} , it gets called, here this is an instance of your class(component), and thus it gives no error to you because handleIncrement method does exist in your class scope, but when you are under handleIncrement method you are using this to update the state which exist in the scope of class(component), but currently you are within the scope of handleIncrement method and so it gives you an error as under addUser Scope you got nothing like state, counter etc. So to deal with this problem you need to bind this while you are calling handleIncrement method.So that your method always knows the instance of this. In Simple Event Handler we don’t want any other variable of the component so we are not at all using this instance and that’s why its working without binding.
Different ways to implement Event Handling in React
1. with bind() in constructor
We have seen this way of Event Handling in above example.
2. with bind() in HTML
JavaScript bind() official doc
<button onClick={this.handleSimpleEvent.bind(this)}>Simple Event Handler</button>
3. With ES6 fat arrow in HTML
Arrow functions, introduced in ES6, provides a concise way to write functions in JavaScript.
Another significant advantage it offers is the fact that it does not bind its own this. In other words, the context inside arrow functions is lexically or statically defined.
Arrow function and this official doc
<button onClick={() => this.handleSimpleEvent()}>Simple Event Handler</button>
You can play with our example on below editor :
Event Handling Stackblitz Example
Lets go to our next tutorial where we will discuss below points :
Part 5- Parent Child Component Communication in React
– Parent to Child component communication in React
1. React props
2. React Context
– Child to Parent component communication in React with callback
https://onlyfullstack.blogspot.com/2019/11/parent-child-component-communication-in-react.html
Source Code
You can edit and play with the react examples on below stackblitz site –
https://stackblitz.com/@onlyfullstack
React Tutorial
https://onlyfullstack.blogspot.com/2019/11/react-tutorial.html