DEV Community

Cover image for React.js: Event Listeners Made Easy
victorhaynes
victorhaynes

Posted on

React.js: Event Listeners Made Easy

If you are a beginner webdev contemplating how to use Event Listeners in React, first of all congratulations on getting your foundation in vanilla JavaScript. That baseline JavaScript understanding is going to come in handy. Second of all, you are in the right place.

Event Listeners in React work, for as far as we are concerned, almost identically to how they work in vanilla JavaScript. There are just some syntactic differences and they get attached to HTML elements in our DOM a bit differently.

The "vanilla JavaScript" way of doings things:

In vanilla JavaScript you may be familiar with this sort of process:

// 1) Create a new button HTML element <button></button>
const newButton = document.createElement("button")

// 2) Assign some attributes to the button
newButton.innerText = "Click Me!"
newButton.setAttribute("class","example-button")

// 3) Assign an Event Listener to the button
newButton.addEventListener("click", () => console.log("You clicked me!")

// 4) Append this new button to the body of our HTML document (or anywhere else we want the button) in the DOM
document.body.append(newButton)

// 5) Your button is now visible on your example HTML page in browser and when clicked 
// it will print "You clicked me" in your console
// FYI: your new HTML button looks like this:
// <button class="example-button">Click Me!</button>

Enter fullscreen mode Exit fullscreen mode

We call this style of programming imperative programming. This means we are being extremely literal and precise. We are specifying every little step and providing clear instructions on how to achieve them. This is not a very React way of doings things. React introduces the concept of declarative programming where we can "declare" what we want to happen and React will handle making it happen.

This same example in React would look like this (assuming you have a React app already initialized). Let's start with a pretty clean slate:

Intro: The React way of doings things

// This file is called App.js
// Here is our baseline React application, right now it only has a
// single Component called "App" and "App" just consists of a <div> node

import React from "react";


function App() {
  return (
    <div className="App">
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Notice how inside the return statement of App it looks like we are writing HTML syntax. That is because we are essentially are with some minor differences (ex. class is used in HTML where in React we use className). React Components render JSX. JSX is a JavaScript extension that allows us to use HTML-like syntax directly inside of a .js file. This is useful because now we can use vanilla JavaScript, HTML, and React-specific features all in the same single .js file. Lets try to build out our vanilla example in React.

Example (pt. 1) - make a button node

// Here we added a button inside of our <div></div>

import React from "react";


function App() {
  return (
    <div className="App">
      <button className="example-button">Click Me!</button>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Wait. What happened to document.createElement("button") and .setAttribute("class", "some-example-class")? In React we no longer need these methods. We can straight up type the HTML we want to render along with any ids or classes directly. We also do not need to .append() anything to our DOM.

If you care to know how exactly these React Components and JSX are getting rendered, the index.js file that is auto generated upon initializing a React app is how. But there are a host of other concepts that make it all happen which are a topic for a different day.

Let's just get an Event Listener working in React. Instead of using .addEventListener() on an HTML node using vanilla JavaScript we can directly add an Event Listener to the JSX node inside the same, single file!

Vanilla JavaScript React
.addEventListener("click", ... onClick={someFunction}
.addEventListener("submit", ... onSubmit={someFunction}
.addEventListener("hover", ... onHover={someFunction}
.addEventListener("change", ... onChange={someFunction}
etc. etc.

Just like how we straight-up-typed the div, the button, the button's innerText, and assigned a class all inside the JSX we can straight-up-type the event listener we want on the JSX also.

Example (pt. 2) - add an onClick to our button & a function to handle the click event

// 1) We defined a function to handle the click event
// 2) We added an onClick event inside the <button> tag

import React from "react";


function App() {

  function handleClick(){
    console.log("You clicked me!")
  }

  return (
    <div className="App">
      <button className="example-button" onClick={handleClick}>
        Click Me!
      </button>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

React Event Listeners must be set equal to something. You want the event listener to be set equal to the function you want to run when the event happens. Specifically, you want to use a function definition and not a function invocation. When our button is clicked on the React application/webpage in our example, "You clicked me!" will be fired off in our console just like in our vanilla JavaScript example.

If you wanted to refactor this a bit you could also the define the post-event-instructions directly inside the onClick and this will achieve the same thing:

Example (pt. 2a) - refactor, define the handler function inline

import React from "react";

function App() {

  return (
    <div className="App">
      <button className="example-button" onClick={() => console.log("You clicked me!")}>
        Click Me!
      </button>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

But back to our Example part 2. There are a few other things going on here. Inside of the same App.js file we are able to 1) write vanilla javascript where we defined our function handleClick and 2) make use of JSX inside of our React Component (inside of App's return statement). Another thing to call out is our use of curly braces {}. Inside the return statement of a React Component the default expectation is everything you type will be JSX. If you need to interpolate vanilla JavaScript inside the return statement of a Component you must wrap the JavaScript inside curly braces {like So}.

And..... Done!

Congratulations on getting this far in your journey towards web development. You are now equipped with the fundamentals on how to use Event Listeners in React.

Top comments (0)