📎 Webclip
99% of frontend devs don't use this
In a list rendered with .map(), Antonio Moruno Gracia contrasts onClick={() => handleClick(item.id)}, a closure recreated for every item on every render, with data-id={item.id} read back out in a single shared handler through e.currentTarget.dataset.id. HTML’s data-* attributes attach the item’s id straight to the DOM element instead of capturing it in a new function each time.
With React.memo or useCallback in place, recreating the closure on every render changes the function reference and invalidates the memoization those tools depend on.
Fichamento#
- With
data-*, metadata attaches straight to the DOM element. A single stablehandleClickfunction reads the id back out throughe.currentTarget.datasetinstead of a new closure getting created for each item in the list. - Since the function reference stays the same across renders, memoization actually prevents the re-render it’s supposed to prevent. A fresh closure defeats that every time, regardless of
React.memooruseCallbackbeing in place. - Moruno frames
data-*as underused because closures are simpler to write and perform fine in most apps, not becausedata-*is objectively better. It becomes worth the extra step in large or re-render-sensitive lists specifically. - Should Junior Developers Still Learn JavaScript the Hard Way? treats closures as one of the core fundamentals worth understanding deeply. This post makes the sharper case for knowing exactly what a closure costs, not just what it is.
