What's the right way to create a memoized callback for use in components that have been created from a .map function?
ie. Here's a non-memoized version of what I want to achieve:
import * as React from "react";
import { render } from "react-dom";
const NUM_BUTTONS = 5;
function App() {
const [value, setValue] = React.useState(0);
return (
<div className="App">
<h1>Value is : {value}</h1>
{new Array(NUM_BUTTONS).fill(true).map((v, i) => (
<button key={i} onClick={() => setValue(i)}>
{i}
</button>
))}
</div>
);
}
const rootElement = document.getElementById("root");
render(<App />, rootElement);
Simple enough.
Now the problem is - I have that inline function which will cause those <button> components to re-render each time this component renders.
One approach I thought of, is to create a list of memoized callbacks, and map over them:
function App() {
const [value, setValue] = React.useState(0);
const callBacks = new Array(NUM_BUTTONS).fill(true).map((v, i) => {
return React.useCallback(() => setValue(i), []);
});
return (
<div className="App">
<h1>Value is : {value}</h1>
{callBacks.map((v, i) => (
<button key={i} onClick={v}>
i
</button>
))}
</div>
);
}
But of course - this breaks one of the Rules of Hooks, you can't call a hook from inside a function or a conditional. Curiously enough, this code still works though.
The alternative I've got, is create a separate <SetValueButton> component that has the value bound to it, like so:
function SetValueButton(props) {
const { value, onClick } = props;
const handleClick = React.useCallback(() => onClick(value), [onClick, value]);
return <button onClick={handleClick}>{value}</button>;
}
function App() {
const [value, setValue] = React.useState(0);
const setValueCb = React.useCallback(i => setValue(i), []);
return (
<div className="App">
<h1>Value is : {value}</h1>
{new Array(NUM_BUTTONS).fill(true).map((v, i) => (
<SetValueButton key = {i} onClick={setValueCb} value={i} />
))}
</div>
);
}
Is this the right idea, or is there a simpler way to do this?
useRef) affects code readability/maintainability in bad way.