about summary refs log tree commit diff
path: root/src/lib/hooks/useNonReactiveCallback.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/hooks/useNonReactiveCallback.ts')
-rw-r--r--src/lib/hooks/useNonReactiveCallback.ts23
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
+}