Skip to content

Commit 1a8928f

Browse files
refactor: replace findNodeHandle for getRefNativeTag (gorhom#1100)(by @AndreiCalazans)
Co-authored-by: Andrei Calazans <andrei.calazans@coinbase.com>
1 parent fe6e054 commit 1a8928f

3 files changed

Lines changed: 47 additions & 4 deletions

File tree

src/hooks/useScrollable.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { useCallback, RefObject, useRef } from 'react';
2-
import { findNodeHandle } from 'react-native';
32
import { useSharedValue } from 'react-native-reanimated';
3+
import { getRefNativeTag } from '../utilities/getRefNativeTag';
44
import { SCROLLABLE_STATE, SCROLLABLE_TYPE } from '../constants';
55
import type { ScrollableRef, Scrollable } from '../types';
66

@@ -38,7 +38,7 @@ export const useScrollable = () => {
3838
// find node handle id
3939
let id;
4040
try {
41-
id = findNodeHandle(ref.current);
41+
id = getRefNativeTag(ref);
4242
} catch {
4343
return;
4444
}

src/hooks/useScrollableSetter.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useCallback, useEffect } from 'react';
2-
import { findNodeHandle } from 'react-native';
32
import Animated from 'react-native-reanimated';
43
import { useBottomSheetInternal } from './useBottomSheetInternal';
4+
import { getRefNativeTag } from '../utilities/getRefNativeTag';
55
import { SCROLLABLE_TYPE } from '../constants';
66
import type { Scrollable } from '../types';
77

@@ -31,7 +31,7 @@ export const useScrollableSetter = (
3131
isContentHeightFixed.value = false;
3232

3333
// set current scrollable ref
34-
const id = findNodeHandle(ref.current);
34+
const id = getRefNativeTag(ref);
3535
if (id) {
3636
setScrollableRef({
3737
id: id,

src/utilities/getRefNativeTag.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
const isFunction = (ref: unknown): ref is Function => typeof ref === 'function';
2+
3+
const hasNativeTag = (
4+
ref: unknown
5+
): ref is { current: { _nativeTag: number } } =>
6+
!!ref &&
7+
typeof ref === 'object' &&
8+
'current' in (ref || {}) &&
9+
'_nativeTag' in ((ref as any)?.current || {});
10+
11+
/*
12+
* getRefNativeTag is an internal utility used by createBottomSheetScrollableComponent
13+
* to grab the native tag from the native host component. It only works when the ref
14+
* is pointing to a native Host component.
15+
*
16+
* Internally in the bottom-sheet library ref can be a function that returns a native tag
17+
* this seems to happen due to the usage of Reanimated's animated scroll components.
18+
*
19+
* This should be Fabric compatible as long as the ref is a native host component.
20+
* */
21+
export function getRefNativeTag(ref: unknown) {
22+
const refType = typeof ref;
23+
let nativeTag: undefined | number;
24+
if (isFunction(ref)) {
25+
nativeTag = ref();
26+
} else if (hasNativeTag(ref)) {
27+
nativeTag = ref.current._nativeTag;
28+
}
29+
30+
if (!nativeTag || typeof nativeTag !== 'number') {
31+
throw new Error(
32+
`Unexpected nativeTag: ${refType}; nativeTag=${nativeTag}
33+
34+
createBottomSheetScrollableComponent's ScrollableComponent needs to return
35+
a reference that contains a nativeTag to a Native HostComponent.
36+
37+
ref=${ref}
38+
`
39+
);
40+
}
41+
42+
return nativeTag;
43+
}

0 commit comments

Comments
 (0)