Abstracting Button Events in React
/ 3 min read
Table of Contents
While building my React & Redux project, I thought about how I can streamline how many functions and components I was using. An example being the game buttons.

“Start Game”, “Food” and “Foe” gameplay buttons
All buttons took in text as a prop
and would need to fire off an action when clicked. If this was built without React, each button would need an event listener, then that event listener would fire off an action. For example.
this.submitButton.addEventListener('click', (e) => { this.createGame(e); });
You could blend multiple actions into one function based on the event that is passed in.
For example, in this function, an “Instructions” section is opened or closed, depending on if it is set to display:block
or display:none
.
this.instructions.addEventListener('click', (e) => { if (this.instructions.style.display == "none") { this.instructions.style.display = "block" } else { this.instructions.style.display = "none" } });
With that in mind, I could do something similar with my React Button
components.
Building the Button
To start, my Button
component looked like this:
<button onClick={this.handleClick}> {this.props.text} // this.props.text = "Start Game", "Food" or "Foe"</button>
Which when clicked, would fire a function handleClick
function.
handleClick = (e) => { this.props.startGame(); // This could be anything}
I could create a handleStartGame
function, a handleFood
, etc, I could simply everything into one function, then fire off specific tasks based on the event (the button) that was clicked.
Abstracting onClick
First, I needed to change the onClick
props to become an anonymous function that takes in the event.
The button goes from this:
<button onClick={this.handleClick}> {this.props.text} // this.props.text = "Start Game", "Food" or "Foe"</button>
To this:
<button onClick={(e) => this.handleClick(e)}> {this.props.text} // this.props.text = "Start Game", "Food" or "Foe"</button>
Now, the handleClick
function can take in the event object. There are no id on the buttons, but the text is unique, we can use that as an identifier.
Switch Case for Event Target
Instead of an if/else
statement, we can do a switch case that looks at the innerText
of the event, and based on that, will fire a specific action.
For example, when the “Start Game’ button is clicked, we want to change the activeGame
attribute in the Redux
store to true
. If the “Food” or “Foe” buttons are clicked, I want it to compare the guess, to the current emoji and return true if the guess is correct or false if it is not.
So let’s work through what’s happening.
switch (e.target.innerText) { case "Start Game": this.props.startGame(); break; case "Food": console.log("The food button was clicked"); this.props.guess(e.target.innerText); break; case "Foe": console.log("The foe button was clicked"); this.props.guess(e.target.innerText); break; default: return}
If the “Start Game” button is clicked, an event object is passed to the function. And the target property of that event object looks like this.
<button>Start Game</button>
From there, we can get to the innerText
which has a value of “Start Game”. Since that meets the first switch case, the startGame
function is fired. If the “Food” button was clicked, the second case is fired, and so one. If there was a fourth button that did not match any of the cases we have specified above, the default case is hit, which is our instance, does not return an action and simply exits the function.
With this setup, I can change what each case does, or add new ones without having to change the functionality of the buttons themselves.