DEV Community

Cover image for Enhancing Dynamic Nature of React Application with Event Handling
Kunal Sharma
Kunal Sharma

Posted on

Enhancing Dynamic Nature of React Application with Event Handling

Starting with event handling requires us to understand what events mean. So, to explain it I would take an example in which I am going to punch a guy which is an action. The guy who got the punch hit is basically JavaScript and now he can have a response to it which can be either to hit me back or run due to my fear. Therefore, the action to which JavaScript can respond is called an event and the response is controlled by the event handler.

Now, talking of general events in an application will be:
1) Clicking an element
2) Submitting a form
3) Scrolling page
4) Hovering an element

Contrasting between event handling in html and react:

In HTML:

<button onclick=”incrementCounter()”>Increment Counter</button> 
Enter fullscreen mode Exit fullscreen mode

In React:

//Used in a function component
<button onClick={incrementCounter}>Increment Counter</button>  
Enter fullscreen mode Exit fullscreen mode
//Used in a class component
<button onClick={this.incrementCounter}>Increment Counter</button>  
Enter fullscreen mode Exit fullscreen mode

So, it can be seen that react events are camelCase. With JSX you only pass the function instead of calling it. Use this keyword in a class component.

Let’s go through one more contrast.

In HTML:

<a href=”#” onclick=”console.log(‘Clicked’); return false”>Click</a>
Enter fullscreen mode Exit fullscreen mode

In React:

function handleClick(e){
    e.preventDefault();
}
<a href=”#” onClick={handleClick}>Click</a>
Enter fullscreen mode Exit fullscreen mode

So, basically you have to call prevent default explicitly in react rather than just returning false.

Another important point is that when you put the callback function to be called on the trigger of the event in order to use ‘this’ work on the callback function either you can have an arrow function or you can use binding this to the function in the constructor.

1) Using arrow function to make ‘this’ work in callback

import React, { Component } from 'react'**

class About extends Component{
    constructor(props){
        super(props);
        this.state = {
            name: "Kunal Sharma"
        }
    }

    handleClick = () => {
        console.log("Button has been clicked", this);
    }

    render(){
        return (
            <div>
                <button onClick={this.handleClick}>Click Me</button>
            </div>
        )
    }
}

export default Student
Enter fullscreen mode Exit fullscreen mode

2) Using binding to use ‘this’ work in callback

import React, { Component } from 'react'

class Student extends Component{
    constructor(props){
        super(props);
        this.state = {
            name: "Kunal Sharma"
        }
        this.handleClick = this.handleClick.bind(this);
    }

    handleClick(){
        console.log("Button has been clicked", this);
    }

    render(){
        return (
            <div>
                <button onClick={this.handleClick}>Click Me</button>
            </div>
        )
    }
}

export default Student
Enter fullscreen mode Exit fullscreen mode

Passing Arguments to event handlers:

1) Arrow Function:

<button onClick={(e)=>this.handleClick(id,e)}>Delete</button>
Enter fullscreen mode Exit fullscreen mode

Here e is react’s event object and id can be a state or props.

2) Bind Method:

<button onClick={this.handleClick.bind(this,id)}>Delete</button>
Enter fullscreen mode Exit fullscreen mode

In both the cases e is passed as an argument to the event handler.
In the arrow function we have implemented it explicitly but with bind it is automatically done.

There are various methods to trigger an event just like onClick. https://reactjs.org/docs/events.html follow this link to have a glance at them and use them as per requirement following the above mentioned ways.

In order to give you much clarity on how I created an app called “Fastest Clicker First” which uses the onClick events and in the event handlers I performed operations like counting the number of times button is being clicked in 10 seconds span of time, changing the states using Boolean variables to mount/unmount and playing the game again by initializing the state to the defaults , resetting the click me button and countdown timer.

App Component:

import React, { Component } from "react";
import Counter from "./components/Counter";
import "./App.css";

class App extends Component {
  constructor(props) {
    super(props);

    this.state = {
      mount: false,
    };

    this.mountCounter = () => this.setState({ mount: true });
    this.unmountCounter = () => this.setState({ mount: false });
  }

  render() {
    return (
      <div className="app">
        <h1>Fastest Clicker First</h1>
        <div className="buttons">
          {!this.state.mount ? (
            <button className="button" onClick={this.mountCounter}>
              Play Now
            </button>
          ) : null}
          {this.state.mount ? (
            <button className="button" onClick={this.unmountCounter}>
              End Game
            </button>
          ) : null}
        </div>
        {this.state.mount ? <Counter /> : null}
      </div>
    );
  }
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Counter Component:

import React, { Component } from "react";
import "./Counter.css";

class Counter extends Component {
  constructor(props) {
    super(props);

    this.state = {
      count: 0,
      timeLeft: 10,
      isActiveButton: true,
      isPlayAgainButtonActive: false,
    };
  }

  incrementCount = () => {
    this.setState({ count: this.state.count + 1 });
  };

  disableClickButton = () => {
    this.setState({ isActiveButton: false });
  };

  componentDidMount = () => {
    this.setCountdownTimer();
    this.resetClickButton();
  };

  setCountdownTimer = () => {
    var timer = setInterval(() => {
      if (this.state.timeLeft > 0) {
        this.setState({ timeLeft: this.state.timeLeft - 1 });
      } else {
        this.setState({ isPlayAgainButtonActive: true });
        clearInterval(timer);
      }
    }, 1000);
  };

  resetClickButton = () => {
    setTimeout(this.disableClickButton, 10000);
  };

  refreshCounter = () => {
    this.setState({ count: 0 });
    this.setState({ timeLeft: 10 });
    this.setState({ isActiveButton: true });
    this.setCountdownTimer();
    this.resetClickButton();
  };

  render() {
    return (
      <div className="counter">
        <h2>Time left is {this.state.timeLeft}</h2>
        <h2>Total number of clicks are {this.state.count}</h2>
        <div className="btns">
          <button
            className="btn"
            onClick={this.incrementCount}
            disabled={!this.state.isActiveButton}
          >
            Click Me
          </button>
          {this.state.isPlayAgainButtonActive ? (
            <button className="button" onClick={this.refreshCounter}>
              Play Again
            </button>
          ) : null}
        </div>
      </div>
    );
  }
}

export default Counter;
Enter fullscreen mode Exit fullscreen mode

Here, in the code you can see in the buttons I have used onClick and in the JSX I have added a callback function which basically will perform the desired response.

Alt Text

You can play this game on https://fastest-clicker-first-2pnc89cjb-kunalsharma1999.vercel.app/

Hope, this example creates a better level of understanding regarding triggering an event and then handling the responses.

That’s it for the post.

Top comments (0)