简体   繁体   中英

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'suseCallback 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?

useEffect has very specific timing aspects related to it that you can read abouthere . 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM