about summary refs log tree commit diff
path: root/src/lib/hooks/useHandleRef.ts
blob: 167ba270b6a63e90a5734449a2a3c267a02f4069 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
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
  }
}