The problem
I want to scroll to an element which is inside of a ScrollView. In order to get the element's scroll position, I'm trying to use measureLayout.
However, if I pass a ScrollView as the "container" in measureLayout, the callback never fires.
How to reproduce
Simplified test case: https://snack.expo.io/@nandorojo/measurelayout-example
Steps to reproduce:
ScrollView, pass it a ref: scrollRefref: textReftextRef.current.measureLayout(scrollRef.current, callback)Expected behavior
The third argument in measureLayout should fire the callback. However, nothing happens.
If I change the "relative to" ref from scrollRef to a View's ref, everything works as expected.
When I run the code on React Native (iOS, Android) it works fine. You'll see this on the Expo Snack URL.
Environment (include versions). Did this work in previous versions?
^0.14.10 (Snack uses an older one, 0.13.x)16.13.1I can't get it to work on older versions.
Additional context
I posted about this on the #web channel on the React Native discord.
@simek reproduced the issue, and mentioned this:
it might be a react-native-web issue, because it look like the implementation only covers the deprecated method signature, which uses node, instead of ref: https://github.com/necolas/react-native-web/blob/master/packages/react-native-web/src/exports/UIManager/index.js#L23
It looks like this is because a ScrollView ref is a React class instance rather than a host node.
it look like the implementation only covers the deprecated method signature, which uses node, instead of ref
I don't know what this means.
@necolas As you can see in the React Native docs the measureLayout has two signatures:
noderefThe new variant of this method seems to fail in react-native-web. The example code in Snack below works on core platforms but has no effect on the Web:
Didn't realise this had changed in 0.64. The plan is to eventually deprecate all the instance methods on RN refs, so I'm not sure why we've changing that API
Didn't realise this had changed in 0.64. The plan is to eventually deprecate all the instance methods on RN refs, so I'm not sure why we've changing that API
The Expo SDK v40 is based on RN 0.63 and if I remember correctly the change has been already a part of one of 0.63 releases, but I wasn't able to find specific changelog entry or commit.
Turns out the RN docs are confusing. You pass ref.current not ref. So there's no issue with the measure function.
The issue is the scrollview ref is not a host component but a component instance. If you wrap the scrollview ref in a findNodeHandle then it works: https://snack.expo.io/ap6i4KVhK
Feel free to update the docs, since you seems to have better understanding what's actually happening in there and additionally you have some internal knowledge too.
The issue is the scrollview ref is not a host component but a component instance. If you wrap the scrollview ref in a findNodeHandle then it works: https://snack.expo.io/ap6i4KVhK
Hmm, but findNodeHandle was an alternative for previous solution and afaik should not be required since method signature refactor. 🤷♂️
I'm not saying it should be required. I'm saying the reason you gave for this issue is incorrect and it is what I've already explained twice.
I believe you can call scrollviewref.getNativeScrollRef().measureLayout(...) to use the non-deprecated API. Using findNodeHandle here is deprecated.
This should be fixed in 0.15.5
Most helpful comment
Turns out the RN docs are confusing. You pass
ref.currentnotref. So there's no issue with the measure function.The issue is the scrollview ref is not a host component but a component instance. If you wrap the scrollview ref in a
findNodeHandlethen it works: https://snack.expo.io/ap6i4KVhK