I have this component
import React from 'react';
import { batch } from 'react-redux';
const ContextMenu = ({
menuData,
isOpen,
changeIsMenuOpen,
changeAssetType,
}) => {
return (
<ClickAwayListener
onClickAway={() => {
batch(() => {
changeIsMenuOpen(false);
changeAssetType(null);
});
}}
>
<ContextMenu
open={isOpen}
menuData={menuData}
/>
</ClickAwayListener>
);
};
that gets its props from following HOC
export default connect(
state => ({
isOpen: selectors.getIsMenuOpen(state),
menuData: selectors.getMenuData(state),
}),
{
changeIsMenuOpen: actions.changeIsMenuOpen,
changeAssetType: actions.changeAssetType,
},
)(ContextMenu);
I thought it might be a good idea to put onClickAway listener to useCallback, so that its instance wont be recreated in every render. Something like
const handleClickAway = useCallback(() => {
batch(() => {
changeIsMenuOpen(false);
changeAssetType(null);
});
}, []);
but i'm not sure what I must put into the dependency array. Should it be all the methods I am using? Something like
[batch, changeIsMenuOpen, changeAssetType]
You should only memoize something when it is actually affecting the application performance.
With that being said, to memoize a function using useCallback
, you need to pass in all the external items you are using in the function.
So, [batch, changeIsMenuOpen, changeAssetType]
is a correct dependency array.
batch
is coming from a library. Also, changeIsMenuOpen
and changeAssetType
seem to be redux actions. So, most likely, they are going to be stable. However, one thing to note is that, if you use some object/function from props which is not memoized, then your memoization is essentially useless since the function will be recreated on every render. In fact, as there are additional checks to maintain a memoized function, your application would have performed slightly better without the memoization.
As a rule of thumb, only memoize things, if re-rendering is costly. Make use of the React's Profiler (https://reactjs.org/docs/profiler.html)