React-native-web: measureLayout doesn't work properly for ScrollView container

Created on 22 Mar 2021  ·  9Comments  ·  Source: necolas/react-native-web

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:

  1. Add a ScrollView, pass it a ref: scrollRef
  2. Add a text inside of the ScrollView, give it a ref: textRef
  3. Call textRef.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?

  • React Native for Web (version): ^0.14.10 (Snack uses an older one, 0.13.x)
  • React (version): 16.13.1
  • Browser: Chrome

I 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

Most helpful comment

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

All 9 comments

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:

The 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.

https://github.com/facebook/react-native/blob/master/Libraries/Components/ScrollView/ScrollView.js#L892

This should be fixed in 0.15.5

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rohanprabhu picture rohanprabhu  ·  3Comments

SamyPesse picture SamyPesse  ·  3Comments

blairio picture blairio  ·  3Comments

necolas picture necolas  ·  3Comments

PaulBGD picture PaulBGD  ·  4Comments