react-native-web
react-native-web copied to clipboard
`measureLayout` relative to `ScrollView` returns incorrect `y` value
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:
- Click on a number in the reproduction. This should scroll to it.
- Look in the console. It outputs the location it should scroll to vs the result of
measureLayout. - Notice that the
yvalue returned frommeasureLayoutis incorrectly subtracting the current scroll position.
To reproduce on your own:
- Add a ScrollView, pass it a
ref: scrollRef - Add a
text inside of the ScrollView, give it a ref: textRef. Put the text far down, maybe give it likemarginTop: 600. - Scroll down a bit.
- Call
textRef.current.measureLayout(scrollRef.current, callback)and log the resultingyvalue from the callback. - 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).
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
});
}
);
};
I'll review a PR for this. Thanks
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 :-).