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.
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
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
useRefCallbackfunction 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