Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the intention of using React's useCallback hook in place of useEffect?

I'm trying to understand what the use case is for using React's useCallback hook in place of the useEffect hook.

They both appear to act as a listener for state changes of their inputs (examples taken from the React Docs):

useEffect(   () => {     const subscription = props.source.subscribe();     return () => {       subscription.unsubscribe();     };   },   [props.source], );  const memoizedCallback = useCallback(   () => {     doSomething(a, b);   },   [a, b], ); 

But, the useEffect hook gives the additional benefit of cleaning up resources where you would have previously with componentWillUnmount.

So, what is a good use case for using useCallback? And, what am I missing here?

like image 598
Don Brody Avatar asked Jan 25 '19 18:01

Don Brody


People also ask

For what purpose is the useCallback () hook used?

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.

Can I use useCallback in useEffect?

Hence, inside the List component, useEffect hook calls the setItems and prints “Fetching items” as its dependency has changed. The solution to the above problem: Here we can use the useCallback function to memoise the getItems() function depending upon the input number.

What is the purpose of using useEffect hook?

The useEffect Hook allows you to perform side effects in your components. Some examples of side effects are: fetching data, directly updating the DOM, and timers. useEffect accepts two arguments. The second argument is optional.

Which of the React hooks is an alternative to useEffect?

The useOnUnmount() hook is a functional React alternative to the ComponentWillUnmount lifecycle method that allows us to mutate values between renders so that it can be used outside the component.


1 Answers

useEffect has very specific timing aspects related to it that you can read about here. The function specified will be executed after rendering is complete and the DOM has been updated. This will happen after each rendering where any of the values specified in the second-argument array change.

useCallback doesn't automatically execute anything. It returns a function that can be executed by whatever code needs to trigger it. There is no listening to changes that causes an execution of the callback. The array values just control what instance of the function is returned. The array values do not control the timing of the function execution.

A key use case is to pass this function as a prop to a child component to use as an event handler. useCallback allows you to define an inline function to use as an event handler (thus it has access to any other variables in the context where the function is defined) without the downside of passing a unique prop to the child every render. So long as the values in the second-argument array have not changed, the same function will be returned as was returned the previous rendering. So if the child component is a pure component, it will not be forced to re-render simply because of always receiving a unique event handler function.

without useCallback

const Parent = ()=> {    const [a, setA] = useState(null);    const eventHandler = ()=> {       // every render creates a unique instance of eventHandler       // even though it always does the same thing so long as 'a' hasn't changed       doSomethingWithA(a);    }    return <Child onClick={eventHandler}/> } 

with useCallback

const Parent = ()=> {    const [a, setA] = useState(null);    const eventHandler = useCallback(()=> {       // A unique function instance is passed in to useCallback on every render, but       // eventHandler will be set to the first instance of this function       // (i.e. potentially an instance of the function that was passed to useCallback       // on a previous rendering) that was passed to useCallback       // for the current value of 'a'.       doSomethingWithA(a);    }, [a]);    return <Child onClick={eventHandler}/> } 

This article provides a bit more detail than the React docs on the use case for useCallback and other hooks.

Related answer: Trouble with simple example of React Hooks useCallback

like image 98
Ryan Cogswell Avatar answered Oct 08 '22 18:10

Ryan Cogswell