Binding Event Handler And Method As Props In React

Introduction

In the previous article, we learned about the destructuring of props and states and the basics of event handling in React. In this article, we will learn about binding event handlers the number of ways binding can be done, and also methods that can be used as props.

Binding Event Handlers

In the previous article, we reviewed what an Event handler is in React. Now in this article, we will go into detail about how to bind event handlers with React. React provides 4 ways to bind the event handlers.

Binding in Render() method

In React, we can attach events using the bind method in a render function. To call the bind method in the render function, we will use .bind(this) in render() function.This is an ES6 class, a plain JavaScript function, therefore, it inherits bind() from function prototype. When using any event inside JSX, this keyword will point to the class instance to which it is called. Using this method may cause performance issues as the function is reallocated on every render. The performance issues may not be visible in small React applications but it may cost very much in bigger React applications.

For example

import React, { Component } from 'react';

class EventBinding extends Component {
    constructor(props) {
        super(props);
        this.state = {
            message: "Testing"
        };
    }

    clickHandler() {
        this.setState({
            message: "Tested"
        });
    }

    render() {
        return (
            <p>
                {this.state.message}
                <button onClick={this.clickHandler.bind(this)}>Test</button>
            </p>
        );
    }
}

export default EventBinding;

Now, export the EventBinding in App.js.

import React, { Component } from "react";
import "./App.css";
import logo from "./logo.svg";
import EventBinding from "./Components/EventBinding";

class App extends Component {
    render() {
        return (
            <p className="App">
                <img src={logo} className="App-logo" alt="logo" />
                <EventBinding></EventBinding>
            </p>
        );
    }
}

export default App;

Now, the output will be displayed as below.

Testing

At the click of a button, the text is changed.

Tested

Arrow function body

This approach uses an arrow function body in the render method

Update the code as shown below.

<button onClick={() => this.clickHandler()}>Test</button>

This will display the output the same as above.

Binding in Constructor

In React, we have another way to bind events, i.e., using binding in the constructor, as shown below.

As per the above example, we will define the event binding in the constructor.

import React from 'react';

class EventBinding extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            message: "Testing"
        };
        this.clickHandler = this.clickHandler.bind(this);
    }

    clickHandler() {
        this.setState({
            message: "Tested"
        });
    }

    render() {
        return (
            <p>{this.state.message}<br/>
                <button onClick={this.clickHandler}>Test</button>
            </p>
        );
    }
}

export default EventBinding;

The output will be the same as shown below.

Output

Localhost

Using this approach will bind the event once in the constructor so it is a better approach than the above 2 and it doesn't rerender on every call.

Class property approach

This approach is an experimental feature. This approach uses the class property as an arrow function. Using class properties, you can simplify your handler functions. This will create a new function on every render.

For example

import React from 'react';

class EventBinding extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            message: "Testing"
        };
    }

    clickHandler = () => {
        this.setState({
            message: "Tested"
        });
    };

    render() {
        return (
            <p>
                {this.state.message}<br/>
                <button onClick={this.clickHandler}>Test</button>
            </p>
        );
    }
}

export default EventBinding;

This will also display the same output as displayed above.

Higher Order Component (HOC)

A Higher Order Component is an advanced technique in React for reusing component logic in our applications. HOCs are a pattern that emerged from the React Composition nature. The HOC is not a part of React API.

The HOC is a function that takes a component and returns a new Component. This plays an important role in reusability.

For example

import React from 'react';

function add(x, y) {
   return x + y;
}

function addFive(x, addReference) {
   return addReference(x, 5);
}

function ParentComponent() {
   return <p>{addFive(10, add)}</p>;
}

export default ParentComponent;

The above code will be displayed as below.

Code

The above example is just a small demo for higher-order components. We can create a much more complex application using Redux which we will learn further in the series.

Method as props

This technique is used to share code between React components using a prop whose value is a function. This is mainly used for reusable code in React. It is used to share the state of one component with another component that needs the same state.

For example, creating a MasterComponent.js file in the React app.

This document has been composed with the free HTML converter. Click here to give it a try.

import React from 'react';

class ParentComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            master: 'master',
            message: ""
        };
        this.greetHandler = this.greetHandler.bind(this);
    }

    greetHandler() {
        this.setState({
            message: `This is ${this.state.master}`
        });
    }

    render() {
        return (
            <p>
                <p>{this.state.message}</p>
                <button onClick={this.greetHandler}>Click Me</button>
            </p>
        );
    }
}

export default ParentComponent;

Now, import ParentComponent in App.js.

import React, { Component } from "react";
import "./App.css";
import logo from "./logo.svg";
import EventBinding from "./Components/EventBinding";

class App extends Component {
    render() {
        return (
            <p className="App">
                <img src={logo} className="App-logo" alt="logo" />
                <EventBinding></EventBinding>
            </p>
        );
    }
}

export default App;

Import ParentComponent in App.js and use it as a tag. Then, the above code will be displayed as below in the browser.

ParentComponent

Master

Now, let's create a child component named ChildComponent.js.

import React from 'react';

function ChildComponent() {
    return (
        <p>
            <button>Call Parent Component</button>
        </p>
    )
}

export default ChildComponent;

Import ChildComponent.js in ParentComponent. The updated code is given below.

import React from 'react';
import ChildComponent from './ChildComponent';

class ParentComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            master: 'master',
            message: ""
        };
        this.greetHandler = this.greetHandler.bind(this);
    }

    greetHandler() {
        this.setState({
            message: `This is ${this.state.master}`
        });
    }

    render() {
        return (
            <p>
                <p>{this.state.message}</p>
                <button onClick={this.greetHandler}>Click Me</button>
                <ChildComponent/>
            </p>
        );
    }
}

export default ParentComponent;

This code will display the output as below.

 Display the output

Now, just modify the code a little bit to call the greetHandler() method from the child as well as parent components.

ParentComponent.js

import React from 'react';
import ChildComponent from './ChildComponent';

class ParentComponent extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            master: 'master',
            message: ""
        };
        this.greetHandler = this.greetHandler.bind(this);
    }

    greetHandler(childName) {
        if (typeof (childName) == 'object') {
            this.setState({
                message: `This is ${this.state.master} `
            });
        } else {
            this.setState({
                message: `This is ${this.state.master} from ${childName}`
            });
        }
    }

    render() {
        return (
            <p>
                <p>{this.state.message}</p>
                <button onClick={this.greetHandler}>I am Parent, Click Me</button>
                <ChildComponent greetChild={this.greetHandler} />
            </p>
        );
    }
}

export default ParentComponent;

ChildComponent.js

The result will be displayed below.

ChildComponent

On a click of the first button, which is available in the parent component, the output will be displayed as below.

First button

On a click of the second button, which is available in the child component, the output will be displayed as below.

 Component

Conclusion

In this article, we learned a number of ways binding for event handlers can be done. Also, we learned how a method can be used as a property. Now in the next article, we will learn about conditional rendering and list rendering in React.

Next in this series: Conditional Rendering and List Rendering in React