useEffect.dev
← Back to lessons

Lesson 8. Optimizing performance with useMemo and useCallback 3. Callbacks for dynamic lists or table rows

Let’s imagine you have a component displaying a list of values, and for each value, you want to show a button to act depending on the value.

Result

In that case, you may wonder how we can use useCallback for the function called when the user presses the button since it depends on the value itself. If we suppose that the rows are updated several dozens of times per second and have hundreds of rows, there would be too many callbacks for good performance.

The trick is that when we have a callback on a button (or any other DOM element), this callback receives a parameter: the DOM event. And this DOM event contains a piece of useful information: the DOM element on which the action was performed.

So if we define an attribute on the button (a data- attribute), then we can get its value in the callback:

<button
data-row-value={row.value}
onClick={(event) => {
const rowValue = event.target.getAttribute('data-row-value')
alert(rowValue)
}}
>
Alert
</button>

For now, nothing changed since we still create a new callback each time the component is rerendered and for each row, but notice that our callback no longer depends on the current row. So we can create it in the component body and use useCallback to make sure it is created only once.

Result