React: Question: Why not useCallback always return static value without deps?

Created on 18 Feb 2020  路  1Comment  路  Source: facebook/react

function useRefCallback<T extends (...args: any) => void>(callback: T) {
  const ref = useRef<T>(callback);
  ref.current = callback;
  return useCallback(function(this: any, ...args: Parameters<T>) {
    return ref.current.apply(this, args);
  } as T, []);
}

I think useRefCallback is safe to replace useCallback in any code, and it's better than useCallback because it will never cause recalculation.

Invalid Question

Most helpful comment

I'm not part of the react team but I hope it's nevertheless okay to give a try to answer your question.

This sounds like a good feature first, but actually it is not really.
It violates one of the core principles of the whole hooks idea that the closures within the component function normally have access (= "close over") to the relevant values at the time the render function had been called.
Using your useRefCallback function will sometimes (mainly in asynchronous situations) lead to cases where you will accidently use "most recent values" instead of "the values at the time of the component function had been called".

This is quite subtle and not really obvious but hopefully the following demo helps a bit to understand:
https://codesandbox.io/s/zealous-bohr-y38te

>All comments

I'm not part of the react team but I hope it's nevertheless okay to give a try to answer your question.

This sounds like a good feature first, but actually it is not really.
It violates one of the core principles of the whole hooks idea that the closures within the component function normally have access (= "close over") to the relevant values at the time the render function had been called.
Using your useRefCallback function will sometimes (mainly in asynchronous situations) lead to cases where you will accidently use "most recent values" instead of "the values at the time of the component function had been called".

This is quite subtle and not really obvious but hopefully the following demo helps a bit to understand:
https://codesandbox.io/s/zealous-bohr-y38te

Was this page helpful?
0 / 5 - 0 ratings