Does it make sense to use useCallback
without deps for simple event handlers?
For example:
const MyComponent = React.memo(() => {
const handleClick = useCallback(() => {
console.log('clicked');
}, []);
const handleOtherClick = () => {
console.log('clicked');
};
return (
<div>
<button onClick={handleClick}>Click me</button>
<button onClick={handleOtherClick}>Click me too</button>
</div>
);
});
What are the pros and cons for using useCallback
in this case?
The useCallback hook is used when you have a component in which the child is rerendering again and again without need. Pass an inline callback and an array of dependencies. useCallback will return a memoized version of the callback that only changes if one of the dependencies has changed.
In most instances, useMemo can be replaced by useCallback, especially for data and methods memorization.
The warning "React Hook useEffect has a missing dependency" occurs when the useEffect hook makes use of a variable or function that we haven't included in its dependencies array. To solve the error, disable the rule for a line or move the variable inside the useEffect hook.
useMemo is very similar to useCallback. It accepts a function and a list of dependencies, but the difference between useMemo and useCallback is that useMemo returns the memo-ized value returned by the passed function. It only recalculates the value when one of the dependencies changes.
The React useCallback Hook returns a memoized callback function. Think of memoization as caching a value so that it does not need to be recalculated. This allows us to isolate resource intensive functions so that they will not automatically run on every render. The useCallback Hook only runs when one of its dependencies update.
React Hook React.useCallback has missing dependencies: 'props.setStatus' and 'statusColumns'. Either include them or remove the dependency array
The original function is recreated regardless of whether you use useCallback or not. Also with the usage of useCallback react actually memoizes the function passed as argument to it, and returns the same reference of the function on next re-render if the dependency didn't change.
Without useCallback Hook: The problem is that once the counter is updated, all three functions are recreated again. The alert increases by three at a time but if we update some states all the functions related to that states should only re-instantiated. If another state value is unchanged, it should not be touched.
Purpose of useCallback
does not depend on if you have dependencies or not. It's to ensure referential integrity. To get better performance. If you need that.
Because for flow having just function or function expression itself make code works well(I mean it does not require us to do any extra action to say referencing actual props etc). So useCallback
is only about performance.
Say we render pure component(instance of React.PureComponent
or functional component wrapped into React.memo
)
function MyComponent() {
const onChangeCallback = ...
return <SomePureComponent onChange={onChangeCallback} />;
}
here if onChangeCallback
is declared as just a function or arrow expression it will be re-created on each render. So it will be referentially different. And nested child will be re-rendered each time while it does not have to.
Another case is listing this callback as dependency in other useCallback
, useMemo
, useEffect
.
function MyComponent() {
const onChangeCallback = ...;
return <Child onChange={onChangeCallback} />
}
...
function Child({onChange}) {
useEffect(() => {
document.body.addEventListener('scroll', onChange);
return () => document.body.removeEventListener('scroll', onChange);
}, [onChange]);
}
Here we also will have referentially different onChange
in Child
without useCallback
. So useEffect
will be run each time parent MyComponent
is called. While we don't need it doing this.
So yes, having empty dependencies list when you don't have actually any dependency is better then declaring function inline without useCallback
at all.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With