use-latest-callback icon indicating copy to clipboard operation
use-latest-callback copied to clipboard

callback isn't latest

Open thomasttvo opened this issue 1 year ago • 1 comments

The best place to reproduce this is in jest, but it may very well happen in real life if the callback is called after awaiting some async operation. The main problem is useIsomorphicLayoutEffect delays setting the new callback, so if there's anything that runs before the effect kicks in, it gets the old callback instead.

- re-render
- new callback is generated, but not set
- async operation calls the wrapper callback
- useIsomorphicLayoutEffect sets new callback
- result: the callback that was called was old

I think the fix here is to just get rid of it and let ref.current = callback runs immediately upon re-render

thomasttvo avatar Sep 11 '24 23:09 thomasttvo

function useLatestCallback<T extends (...args: A) => R, A extends unknown[], R>(callback: T): T {
  const ref = useRef<T>(callback);

  useIsomorphicLayoutEffect(() => {
    ref.current = callback;
  });

  const latestCallback = useCallback((...args: A) => {
    return ref.current(...args);
  }, []);

  return latestCallback as T;
}

export default useLatestCallback;

i think this does the trick

ashwin1014 avatar Sep 20 '24 06:09 ashwin1014