I use this pattern sometimes where I declare a curried function inside useCallback
.
const Child = ({ handleClick }) => {
return (
<>
<button onClick={handleClick("foo")}>foo</button>
<button onClick={handleClick("lorem")}>lorem</button>
</>
);
};
export default function App() {
const [state, setState] = useState("");
const handleClick = useCallback(
(newState) => () => {
setState(newState);
},
[]
);
return (
<div className="App">
<Child handleClick={handleClick} />
<p>{state}</p>
</div>
);
}
because I want to pass arguments from JSX to the event handlers and to avoid multiple handlers.
When the component rerenders, handleClick
will be called and the function that is returned will be assigned to the onClick
prop, but will it be a new function every time or will the nested function also get memoized by useCallback
?
PS: This is a simple example. Assume a useCallback
usage with multiple dependencies
Following answer refers to the initial version of the OP's code in which handleClick
was not passed as a prop to Child
component.
You don't really need useCallback
in this case.
Actually, it would be better not to use the useCallback
hook in this case because:
Callback function passed to useCallback
is created everytime your component re-renders. As a result, a new function is getting created anyways, just like it would without the use of useCallback
Getting a memoized version of the handleClick
function doesn't provides any benefit in your case. Memoization would be useful if handleClick
is passed as a prop to child component(s).
...but will it be a new function every time or will the nested function also get memoized by useCallback?
No, the nested function won't be memoized.
handleClick
is a memoized function but that memoized function returns a new function everytime it executes.
Invoking handleClick
is just like invoking any other function - anything declared inside its body is created everytime it is invoked.