about summary refs log tree commit diff
path: root/src/lib/hooks/useHandleRef.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/hooks/useHandleRef.ts')
-rw-r--r--src/lib/hooks/useHandleRef.ts39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/lib/hooks/useHandleRef.ts b/src/lib/hooks/useHandleRef.ts
new file mode 100644
index 000000000..167ba270b
--- /dev/null
+++ b/src/lib/hooks/useHandleRef.ts
@@ -0,0 +1,39 @@
+import {useState} from 'react'
+import {AnimatedRef, measure, MeasuredDimensions} from 'react-native-reanimated'
+
+export type HandleRef = {
+  (node: any): void
+  current: null | number
+}
+
+// This is a lighterweight alternative to `useAnimatedRef()` for imperative UI thread actions.
+// Render it like <View ref={ref} />, then pass `ref.current` to `measureHandle()` and such.
+export function useHandleRef(): HandleRef {
+  return useState(() => {
+    const ref = (node: any) => {
+      if (node) {
+        ref.current =
+          node._nativeTag ??
+          node.__nativeTag ??
+          node.canonical?.nativeTag ??
+          null
+      } else {
+        ref.current = null
+      }
+    }
+    ref.current = null
+    return ref
+  })[0] as HandleRef
+}
+
+// When using this version, you need to read ref.current on the JS thread, and pass it to UI.
+export function measureHandle(
+  current: number | null,
+): MeasuredDimensions | null {
+  'worklet'
+  if (current !== null) {
+    return measure((() => current) as AnimatedRef<any>)
+  } else {
+    return null
+  }
+}