How would you avoid new functions per list item without useCallback?

Tests stable handler patterns for large lists. Answer: define one handler outside the map, attach it to every item, and read the id from a data-id attribute via currentTarget.dataset.id. Or use event delegation on the parent. Red flag: useCallback in loop.
What's really being asked
This question probes whether you understand function identity in React and can optimize large lists without placing hooks inside loops. The interviewer wants to see if you know how to keep a single event handler reference while still accessing dynamic item data. It also checks your mental model of the synthetic event system and whether you reach for data attributes or event delegation instead of closures.
The full answer
First, define one handler function completely outside the map so its reference stays stable across renders. Second, store the item id in a data attribute such as data-id on each rendered element. Third, inside that single handler read event.currentTarget.dataset.id to identify which item was clicked. This creates exactly one function regardless of list size. An alternative valid approach is event delegation: attach one onClick to the parent container, then use event.target.closest to find the clicked item element and read its dataset. Both approaches avoid allocating N functions every render. You should mention that the benefit is most visible in very large or rapidly updating lists where GC pressure and child re-render overhead accumulate.
The mistakes people make
Suggesting useCallback inside the map is a rules-of-hooks violation and an immediate red flag. Recommending React.memo on a child component without explaining how the handler itself avoids re-creation misses the point because the child still receives a new inline arrow each render. Producing a handler via bind inside the loop also creates a new function per item. Saying that modern React is fast enough to ignore the issue signals a lack of performance awareness at scale.
What usually comes next
The interviewer may ask how you would handle keyboard accessibility for these items, since divs with onClick are not focusable by default. They might ask how React synthetic event delegation interacts with your solution, or what happens if the list items contain nested interactive elements like buttons. Another follow-up is comparing memory usage between data-attribute handlers and a ref-based lookup map.
A concrete example
Imagine a list of ten thousand messages. Instead of messages.map m => div onClick equals an inline arrow calling handleOpen with m.id, you write const handleClick equals e arrow function with const id equals e.currentTarget.dataset.id and then handleOpen id, and render div data-id equals m.id onClick equals handleClick. This uses one function for the entire list. If the container is a ul, you could instead put onClick equals handleContainerClick on the ul and use e.target.closest li to find the message row.
Interview question
Which approach correctly optimizes a large mapped list by keeping a single stable onClick reference while still identifying the clicked item?
- a.Define one handler outside the map and read the item id from event.currentTarget.dataset.idCorrect
- b.Call .bind inside the map to preset the id argument for a shared handler function
- c.Wrap each item with useCallback inside the map to memoize individual handlers
- d.Apply React.memo to each list item so inline arrow handlers do not cause re-renders
Why? this is the answer
Defining one handler outside the map and reading the id from event.currentTarget.dataset.id creates exactly one stable function reference regardless of list size. Wrapping items with useCallback inside the map violates the rules of hooks and still allocates N functions, while React.memo alone cannot prevent inline arrows from being recreated each render.
Just read this? Test yourself on what you have been reading.
Read the original → react.dev
- #react
- #performance
- #event-handlers
- #lists
- #interview
You just looked this up. Could you explain it out loud?
That is the part interviews actually test. Tezvyn takes questions like this one and gives you what the interviewer is really checking, the answer that lands, and the mistake that ends the conversation, in the four minutes before your next meeting.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Open roles that interview on react — each one lists the topics its interview covers.
See open roles