Packt_Pub
Packt_Pub
Dec 6, 2018 · 4 min read

Learn how to declare event handlers in this article by Adam Boduch, a seasoned web application developer with a breadth of experience ranging from jQuery to React and everything in between.

React has a unique approach to handling events: declaring event handlers in JSX. The differentiating factor with event handling in React components is that it’s declarative. Contrast this with something like jQuery, where you have to write imperative code that selects the relevant DOM elements and attaches event handler functions to them.

The advantage with the declarative approach to event handlers in JSX markup is that they’re part of the UI structure. Not having to track down the code that assigns event handlers is mentally liberating. In this article, you’ll write a basic event handler, so you can get a feel for the declarative event handling syntax found in React applications. Then, you’ll learn how to use generic event handler functions.

Declaring handler functions

Here’s a look at a basic component that declares an event handler for the click event of an element:

import React, { Component } from 'react';
export default class MyButton extends Component {
// The click event handler, there's nothing much happening here other than a log of the event.
onClick() { console.log('clicked');}
// Renders a "<button>" element with the "onClick" event handler set to the "onClick()" method of this component. render() { return ( <button onClick={this.onClick}>{this.props.children}/> ); }}

The event handler function, this.onClick(), is passed to the onClick property of the <button> element. By looking at this markup, it's clear what code is going to run when the button is clicked.

Multiple event handlers

The declarative event handler syntax is easy to read when there’s more than one handler assigned to an element. Sometimes, for example, there are two or three handlers for an element. Imperative code is difficult to work with for a single event handler, let alone several of them. When an element needs more handlers, it’s just another JSX attribute. This scales well from a code maintainability perspective:

import React, { Component } from 'react';
export default class MyInput extends Component {// Triggered when the value of the text input changes...onChange() { console.log('changed');}// Triggered when the text input loses focus...onBlur() { console.log('blurred');}// JSX elements can have as many event handler properties as necessary. render() { return <input onChange={this.onChange} onBlur={this.onBlur} />; }}

This <input> element could have several more event handlers, and the code would be just as readable.

As you keep adding more event handlers to your components, you’ll notice that a lot of them do the same thing. Next, you’ll learn how to share generic handler functions across components.

Importing generic handlers

Any React application is likely going to share the same event handling logic for different components. For example, in response to a button click, the component should sort a list of items. It’s these types of generic behaviors that belong in their own modules so that several components can share them. Implement a component that uses a generic event handler function:

import React, { Component } from 'react';// Import the generic event handler that manipulates the state of a component.import reverse from './reverse';export default class MyList extends Component {  state = {    items: ['Angular', 'Ember', 'React']  };
// Makes the generic function specific to this component by calling "bind(this)".onReverseClick = reverse.bind(this);render() { const { state: { items }, onReverseClick } = this; return ( <section>{/* Now we can attach the "onReverseClick" handler to the button, and the generic function will work with this component's state. */} <button onClick={onReverseClick}>Reverse</button> <ul>{items.map((v, i) => <li key={i}>{v}</li>)}</ul> </section> );}}

You’re importing a function called reverse(). This is the generic event handler function that you're using with your <button> element. When it's clicked, the list should reverse its order.

The onReverseClick method actually calls the generic reverse() function. It is created using bind() to bind the context of the generic function to this component instance.

Finally, looking at the JSX markup, you can see that the onReverseClick() function is used as the handler for the button click.

So how does this work, exactly? Do you have a generic function that somehow changes the state of this component because you bound context to it? Well, pretty much, yes, that’s it. Here’s look at the generic function implementation now:

// Exports a generic function that changes the state of a component, causing it to re-render itself.export default function reverse() {  this.setState(this.state.items.reverse());}

This function depends on a this.state property and an items array within the state. The key is that the state is generic; an application could have many components with an items array in its state.

Here’s what your rendered list looks like:

As expected, clicking on the button causes the list to sort, using your generic reverse() event handler:

If you found this article interesting, you can explore React and React Native — Second Edition to build applications for web and native mobile platforms with React, JSX, Redux, and GraphQL. React and React Native — Second Edition takes you through using React 16 and React Native 0.5 to create powerful and engaging desktop mobile and native applications for all platforms.

JavaScript in Plain English

Learn the web's most important programming language.

Packt_Pub

Written by

Packt_Pub

Stay Relevant!

JavaScript in Plain English

Learn the web's most important programming language.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade