Simple Naming Tips for Event Handlers

Helping our team (and ourselves) write more meaningful and robust code

Vlad Sabev

--

🎯 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’s save event, and we already use the on 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 👇

--

--