Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

measureLayout relative to ScrollView returns incorrect y value #2109

Open
nandorojo opened this issue Aug 22, 2021 · 3 comments · May be fixed by #2570
Open

measureLayout relative to ScrollView returns incorrect y value #2109

nandorojo opened this issue Aug 22, 2021 · 3 comments · May be fixed by #2570
Labels
project:react-native-web Issue associated with react-native-web

Comments

@nandorojo
Copy link
Contributor

nandorojo commented Aug 22, 2021

The problem

Calling measureLayout relative to a ScrollView returns the incorrect y value when the scroll position is greater than 0.

How to reproduce

Simplified test case: https://codesandbox.io/s/lucid-sea-rq0ny?file=/src/App.js:0-1339

Steps to reproduce:

  1. Click on a number in the reproduction. This should scroll to it.
  2. Look in the console. It outputs the location it should scroll to vs the result of measureLayout.
  3. Notice that the y value returned from measureLayout is incorrectly subtracting the current scroll position.

To reproduce on your own:

  1. Add a ScrollView, pass it a ref: scrollRef
  2. Add a text inside of the ScrollView, give it a ref: textRef. Put the text far down, maybe give it like marginTop: 600.
  3. Scroll down a bit.
  4. Call textRef.current.measureLayout(scrollRef.current, callback) and log the resulting y value from the callback.
  5. Notice that it does not give you the distance from the top of the scrollable content; rather, it gives you the distance from the top of the ScrollView, minus the scroll position.

Expected behavior

The behavior should match that of native. Try the example on iOS here, and notice that it always scrolls to the correct spot: https://snack.expo.dev/@beatgig/dedc14

On native, calling measureLayout relative to a ScrollView gives the y coordinate relative to the top of the the scrollable content, regardless of scroll position.

Environment (include versions). Did this work in previous versions?

  • React Native for Web (version): 0.17.0
  • React (version): 17.0.2
  • Browser: Chrome

It doesn't work in any previous versions, tried back to 0.15.x, where measureLayout was initially implemented for ScrollViews (#1957).

@nandorojo
Copy link
Contributor Author

In case anyone needs a temporary solution, you can use getInnerViewRef() if Platform.OS === 'web':

const scrollTo = (index) => () => {
    viewRefs.current[index].measureLayout(
-     scrollRef.current,
+     scrollRef.current.getInnerViewRef(),
      (x, y) => {
        scrollRef.current.scrollTo({
          y,
          animated: true
        });
      }
    );
  };

@necolas
Copy link
Owner

necolas commented Sep 28, 2021

I'll review a PR for this. Thanks

@mikehardy
Copy link

For whatever reason I was looking at react-native-anchor today in combination with react-native-web and just wanted to note that this is apparently still an active issue requiring a patch to react-native-anchor in order to scroll reliably on web. I had a brief investigation into providing the needed PR here as there is not one in the PR queue yet, but don't quite have the domain knowledge in react-native-web to do so. Perhaps in the future. But it's an active / actively-worked-around issue at the moment, ready for a PR from you, dear reader, according to the comment above :-).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
project:react-native-web Issue associated with react-native-web
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants