Simple Naming Tips for Event Handlers
Helping our team (and ourselves) write more meaningful and robust code
🎯 The Challenge
Here’s something we’ve probably all seen— component methods named after the events they’re handling:
In addition to React, I’ve also seen this pattern in Angular, Backbone, jQuery…it has probably existed for as long as the first programming language that had event handlers.
Here’s an example with event listeners in vanilla JavaScript:
const modal = document.querySelector('#confirmation-modal');
modal.addEventListener('yes', onYes);
modal.addEventListener('no', onNo);
modal.addEventListener('close', onClose);
For the difference between event handlers and listeners see this definition on MDN. The tips in this post apply to both.
Okay, so handler names like onYes
, onNo
, onClose
…what about them?
⚠ Duplicate functionality
In the EditForm
component it’s relatively easy to see that this.onNo
and this.onClose
do the exact same thing — especially since they’re defined right next to each other!
Of course we can change those events to use the same handler:
...
<ConfirmationModal
onYes={this.onYes}
onNo={this.onClose}
onClose={this.onClose}
>
...
Whew! Problem solved? Perhaps, at least in this case.
Now think about this for a second — if we continue this practice of naming all handlers based on the events that trigger them, how likely is it that we’d introduce duplicates like this in the future?
And how likely is it that we’d miss those duplicates in a large and complex component?
⚠ Short-lived names
Eh, maybe we don’t care about duplicates as much — our code works fine and at least the naming is consistent.
Oh look, our colleague Jane just found a really awesome open source modal library that looks utterly amazing!
She’s now starting to use it across the whole application, and asks us to help by also changing it in the EditForm
since we're working on that component anyway.
So we do:
...
<AwesomeModal
onConfirm={this.onYes}
onCancel={this.onClose}
>
...
Hmm, looks like the event names for this one are a bit different. It actually doesn’t even have onClose
anymore.
Our code still works fine — it’s just the naming that has become inconsistent!
What do we do? Should we rename all our handlers now?
💭 The Suggestion
I think we should!
And if we want the new names to stick around, I would suggest we base them on what they do instead of when they do it.
Here’s our EditForm
using the original ConfirmationModal
component, but with a different way of naming event handlers:
What differences did you see?
For example did you notice how we now used this.hideDiscardModal()
in multiple places instead of this.setState({ discardModalIsShown: false })
?
It’s much easier to think of using something when we put a meaningful name to it.
hideDiscardModal
carries more meaning about what it does than onNo
, so we’ll naturally think of it in more situations where we need to…you know…hide the discard modal.
🤔 The Dilemma
We’ve renamed all the component’s handlers, yet its props are still called onSave
and onDiscard
instead of save
and discard
respectively.
Should we rename them too?
I’ve heard both opinions — my preference is to keep the on
prefix, as they’re event names, not handlers.
Think of
onSave
as something that allows subscribing to the component’ssave
event, and we already use theon
prefix for that in JavaScript.
📝 The Summary
When handling events like this:
<ConfirmationModal
onYes={this.discard}
onNo={this.hideDiscardModal}
onClose={this.hideDiscardModal}
/>
We followed these simple naming tips:
1. Event names should answer the question when, because they’re on the left side and describe the conditions under which events trigger.
2. Handler names should answer the question what, because they’re on the right side and describe the effects that events have.
What’s the way you do it? Got any further naming tips?
Let me know in the comments 👇