From 54bf5ce2d181d6e0782dbb68670c9744289f2ba9 Mon Sep 17 00:00:00 2001 From: mstach60161 Date: Mon, 22 May 2023 14:02:02 +0200 Subject: [PATCH] Fix animatedRef on Fabric (#4445) ## Summary - Fixes #4256 ### Problem If the scrollable component is not root, UI `scrollTo` doesn't work on Fabric. #4384 - It was fixed here for Paper, but after this change app crashes on Fabric, because `getScrollableNode` in both architectures returns viewTag as a number, not component. It's working for Paper, because we are passing either component or number to `findNodeHandle` method, but on Fabric we need component ref. ### Fix Instead of `getScrollableNode`, we can use `getNativeScrollRef` and get scrollable reference. ### TODO Unfortunately this method is not implemented yet for `Flash-list` -> https://shopify.github.io/flash-list/docs/usage#:~:text=Unsupported%20methods%3A so for now, UI `scrollTo` on FlashList works only for Paper Architecture. ## Test plan ScrollToExample: - Paper, ScrollView - Paper, FlatList - Fabric, ScrollView - Fabric, FlatList --------- Co-authored-by: Tomek Zawadzki --- src/reanimated2/hook/useAnimatedRef.ts | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/reanimated2/hook/useAnimatedRef.ts b/src/reanimated2/hook/useAnimatedRef.ts index d7739ac396e..a11a3d29de9 100644 --- a/src/reanimated2/hook/useAnimatedRef.ts +++ b/src/reanimated2/hook/useAnimatedRef.ts @@ -10,6 +10,7 @@ import { } from '../shareables'; interface ComponentRef extends Component { + getNativeScrollRef?: () => ComponentRef; getScrollableNode?: () => ComponentRef; } @@ -19,6 +20,15 @@ function getShareableShadowNodeFromComponent( return getShadowNodeWrapperFromHostInstance(component); } +function getComponentOrScrollableRef(component: ComponentRef): ComponentRef { + if (global._IS_FABRIC && component.getNativeScrollRef) { + return component.getNativeScrollRef(); + } else if (!global._IS_FABRIC && component.getScrollableNode) { + return component.getScrollableNode(); + } + return component; +} + const getTagValueFunction = global._IS_FABRIC ? getShareableShadowNodeFromComponent : getTag; @@ -31,11 +41,7 @@ export function useAnimatedRef(): RefObjectFunction { const fun: RefObjectFunction = >((component) => { // enters when ref is set by attaching to a component if (component) { - tag.value = getTagValueFunction( - component.getScrollableNode - ? component.getScrollableNode() - : component - ); + tag.value = getTagValueFunction(getComponentOrScrollableRef(component)); fun.current = component; } return tag.value; @@ -50,7 +56,6 @@ export function useAnimatedRef(): RefObjectFunction { }, }); registerShareableMapping(fun, remoteRef); - ref.current = fun; }