diff options
author | dan <dan.abramov@gmail.com> | 2023-11-17 02:01:51 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-11-16 18:01:51 -0800 |
commit | 3043b324681f1702ca53831701fb5cecd14c0efb (patch) | |
tree | 7a8ba883a158870b95e94af1c11afa3913398ee3 /src/lib/hooks/useNonReactiveCallback.ts | |
parent | c03c744008bc15be807ccb172801268bd24dae53 (diff) | |
download | voidsky-3043b324681f1702ca53831701fb5cecd14c0efb.tar.zst |
Fix jumpy modal regression (#1945)
Diffstat (limited to 'src/lib/hooks/useNonReactiveCallback.ts')
-rw-r--r-- | src/lib/hooks/useNonReactiveCallback.ts | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/src/lib/hooks/useNonReactiveCallback.ts b/src/lib/hooks/useNonReactiveCallback.ts new file mode 100644 index 000000000..4b3d6abb9 --- /dev/null +++ b/src/lib/hooks/useNonReactiveCallback.ts @@ -0,0 +1,23 @@ +import {useCallback, useInsertionEffect, useRef} from 'react' + +// This should be used sparingly. It erases reactivity, i.e. when the inputs +// change, the function itself will remain the same. This means that if you +// use this at a higher level of your tree, and then some state you read in it +// changes, there is no mechanism for anything below in the tree to "react" +// to this change (e.g. by knowing to call your function again). +// +// Also, you should avoid calling the returned function during rendering +// since the values captured by it are going to lag behind. +export function useNonReactiveCallback<T extends Function>(fn: T): T { + const ref = useRef(fn) + useInsertionEffect(() => { + ref.current = fn + }, [fn]) + return useCallback( + (...args: any) => { + const latestFn = ref.current + return latestFn(...args) + }, + [ref], + ) as unknown as T +} |