A pattern I see everywhere in web dev: people name their event handlers as handle
plus the upper-cased name of the event.
function handleClick (event) {...}
function handleKeydown (event) {...}
function handleFocus (event) {...}
A while back, I started naming these handlers with the normal, lower-cased name of the event, plus Effect
.
function clickEffect (event) {...}
function keydownEffect (event) {...}
function focusEffect (event) {...}
I think this is better for a few different reasons.
First, these functions don't just "handle" events (what does that even mean?)—they perform side effects. They update reactive references, store data in app state, change something in the DOM, etc. The word Effect
in the function's name makes that very clear.
Also, it plays nice with multi-cursor editing. I can't event tell you how many times I've had to change click
and Click
independently, even thought they're the exact same word in the exact same context, just because one of them happens to be prefixed by handle
. So annoying!
// Use multi-cursor editing to easily select both,
// and change them in one go.
element.addEventListener('click', clickEffect)
Using Effect
instead of handle
also helps me move further away from agent nouns, specifically the noun "handler", which we tend to use all the time when describing these callback functions. The reasons for avoiding agent nouns are generally more relevant in object-oriented programming, and not so much when we're dealing with plain functions, but I find it's still a good habit to keep.
And finally, the word Effect
creates a clear connection between my functions and some other important tools I use in front end dev:
// In React, we have `useEffect`. By using this hook,
// we're saying, "When something happens to the listed
// dependencies, perform a side effect."
useEffect(
() => {...},
[...]
)
// In Vue, we have `watchEffect`. The purpose is similar:
// "When something happens to the collected dependencies,
// perform a side effect."
watchEffect(() => {...})
// Our "handlers", by using "Effect" in their name,
// take on a new meaning: "When a specific type of thing
// happens to an element, perform a side effect."
clickEffect (...) {...}
This connection highlights some other super important similarities between the side effects performed by useEffect
and watchEffect
, and the side effects we perform when DOM events fire:
- In many cases, side effects need to be properly timed with other effects that might be mutating the same state, otherwise unexpected results will happen.
- Side effects need to be cleaned up in order to avoid memory leaks.
useEffect
lets you return a cleanup function, andwatchEffect
gets cleaned up automatically.clickEffect
needs to be removed viaremoveEventListener
when you're done with it.
"Effect" is better than "Handle"!