Event Handler Functions

By Yeo Yong Kiat in ReactJS

10 min read
So far, all we've really done is to code a static webpage in React, which isn't much of an app. We are now in a good position to look at how to insert "handler functions" - these are functions that respond to certain events occuring in the browser.

Creating an Interactive HTML Element

In web development, an event is a term referring to the specific instance when a DOM element is being updated or manipulated. Unfortunately, there doesn't seem to be anything in our app thus far that we can interact with. So, let's create something that we can at least interact with - a textinput field:

import React from 'react';
import {v4 as uuidv4} from 'uuid';

// I used a placeholder code fragment (...) here for brevity
const data = {...};

// Insert textinput element here
function App() {
  return (
    <div className="appContainer">
      <h1>{data.title}</h1>
      <p>{data.contents}</p>      
      <Bullet />
      <label htmlFor="search">Search: </label>
      <input id="search" type="text" />
    </div>
  );
}

export default App;

Notice anything odd above? Well, just like how we use "className" instead of "class" in React, we also use "htmlFor" instead of the "for" attribute. You should now see the following webpage being rendered:

Best App

That's right baby!

  • Item 1
  • Item 2
  • Item 3

Event Handler Functions

Next, let's create a function called a handler function to deal with any change that takes place in the text input field. For starters, let's log to the console everything we type. To do so, we create a function called "handleChange" (you can call this anything, really) in App.js above the "return()" section, and then reference this function in the textinput element with an "onChange" attribute:

import React from 'react';
import {v4 as uuidv4} from 'uuid';

const data = {...};

function App() {
  // Create handleChange function here
  const handleChange = (event) => {
        console.log(event.target.value);
  }

  // Pass handleChange to textinput element
  return (
    <div className="appContainer">
      <h1>{data.title}</h1>
      <p>{data.contents}</p>      
      <Bullet />
      <label htmlFor="search">Search: </label>
      <input id="search" type="text" 
       onChange={handleChange} />
    </div>
  );
}

export default App;

Again, notice anything odd?

  • Instead of the typical "onchange" attribute, we use a camelcase "onChange" attribute. This will be the case for all event detection attributes in React.
  • Notice how we pass the function "handleChange" itself to the "onChange" attribute, as opposed to passing the value of the function "handleChange()".

With this go back to where your app is hosted at http://localhost:3000 and open your JS console. Your JS console should now log the value of whatever you're typing into the input textfield, as follows:

example of event handling

Time for Another Component?

You might think that this text input element seems to be performing a specialised function within our app, and thus seems to fit within a standalone React component. If you're thinking that, you thought right! Let's create our third React component by extracting out the textinput JSX section into a component called "Search.js":

// Save this as "Search.js"
import React from 'react';

function Search() {
    const handleChange = (event) => {
        console.log(event.target.value);
    }

    return(
        <label htmlFor="search">Search: </label>
        <input id="search" type="text" 
        onChange={handleChange} />
    )
};

export default Search;

And you know the drill - go back to App.js, import the "Search.js" component, and reference it in the JSX section:

import React from 'react';
import {v4 as uuidv4} from 'uuid';

// Import "Search.js" here
import Search from './Search';

const data = {...};

function App() {
  const handleChange = (event) => {
        console.log(event.target.value);
  }

  // Reference "Search" here
  return (
    <div className="appContainer">
      <h1>{data.title}</h1>
      <p>{data.contents}</p>      
      <Bullet />
      <Search />
    </div>
  );
}

export default App;

Before we end this post, some of you may notice that we have also cut out the function definition of "handleChange" into "Search.js" rather than retaining it in App.js. Admitably, this is not the React way of doing things - preferably, we would like to have all functions and data reside in the parent container, and then pass them on to their children. But we haven't quite touched on state and props yet, so we will leave this to a future article.

Let's discuss the concept of state in the next article.

Find more ReactJS stories on my blog. Have a suggestion? Contact me at [email protected].