I'm trying to learn about the hooks functionality, however I can't quite seem to figure out how I'm supposed to use the function useCallback
properly. As far as I understand from the rules about hooks I'm supposed to call them top-level and not within logic (such as loops). Which leads me to be quite confused how I'm supposed to implement useCallback
on components that are rendered from a loop.
Take a look at the following example snippet where I create 5 buttons with an onClick
handler that prints the number of the button to the console.
const Example = (props) => {
const onClick = (key) => {
console.log("You clicked: ", key);
};
return(
<div>
{
_.times(5, (key) => {
return (
<button onClick={() => onClick(key)}>
{key}
</button>
);
})
}
</div>
);
};
console.log("hello there");
ReactDOM.render(<Example/>, document.getElementById('root'));
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id='root'>
</div>
Right now it creates a new function instance everytime the Example renders due to my use of the arrow function within the <button onClick={() => onClick(key)}>
, which I do because I want the onClick
function to know which button called it. I thought I could prevent this with the new react hooks functionality by using useCallback
, however if I apply it to the const onClick
then it would still create a new instance every render because of the inline arrow function needed to give the key
parameter, and I'm not allowed to apply it to the render within a loop as far as I know (especially if the loop order might change right?).
So how would I go about implementing useCallback
in this scenario while keeping the same functionality? Is it at all possible?
data-*
attributes part of this answer is also provided in the React documentation for optimizing callback events for a large number of elements – Coronel