Reputation: 7618
I have a <Tabs />
component in material-ui, that has a handler for changing mode. The on change has this signature (from the link):
Signature:
function(event: object, value: any) => void
event: The event source of the callback
value: We default to the index of the child (number)
My implementation goes a little something like this:
<Tabs
value={mode}
onChange={handleChange}
/>
<Tab id="choice1" value="one" label="Choice 1" />
<Tab id="choice2" value="two" label="Choice 2" />
</Tabs>
My handleChange
function is just an arrow fn around a useState-like hook
const handleChangeMode = (event, newMode) => {
setMode(newMode);
}
In an effort to avoid recreating this arrow fn each time, I've tried to do this:
const handleChangeMode = useCallback((event, newMode) => {
setMode(newMode);
}, [setMode]);
but I noticed, that the thing that changes the most, the new mode isn't part of the deps, and thus would perhaps not behave properly? Then I conjured this monstrosity from my darkest dreams:
const handleChangeMode = useCallback((event, newMode) => {
useCallback(() => setMode(newMode), [setMode, newMode])();
}, [setMode]);
It's callbacks all the way down.
Previously, this question (React hooks useCallback with parameters inside loop) suggested not to use useCallback
in that scenario. But as this is something that could be called over and over, it seems like the place to do so. Also the example with useMemo
doesn't get around that I want to depend on a variable passed into the hook, which I don't even think works in this example (e.g. I'm using the hook wrong, as well as not knowing how to use it for my example).
How do I get around this issue?
(Edit: in fact, I cannot nest the callback/memo hooks at all. so the last code example doesn't work, as I suspected)
Upvotes: 2
Views: 5926
Reputation: 5179
You ask:
but I noticed, that the thing that changes the most, the new mode isn't part of the deps, and thus would perhaps not behave properly?
const handleChangeMode = useCallback((event, newMode) => {
setMode(newMode);
}, [setMode]);
Answer: No, this code will behave properly. You need to add props to dependencies only if you use them directly from component. For example:
const { mode } = props;
const handleChangeMode = useCallback((event) => {
setMode(mode);
}, [setMode, mode]);
In your case you get newMode
as argument of a function. So you don't need to add it as a dependency.
Upvotes: 3