react-native-web
react-native-web copied to clipboard
measureInWindow doesn't work properly for multiple similar mounted components
Is there an existing issue for this?
- [X] I have searched the existing issues
Describe the issue
After upgrading from 0.18.4 to 0.19.8 version (and tried other 0.19.x with same result), measureInWindow returns the same result for all similar mounted components.
In out case the modal is rendered in the same position for all dropdowns - at the most top dropdown.
Here on the screenshot the focused combobox was clicked, but modal appeared at the first one.
On 0.18.4 version it works.
Expected behavior
measureInWindow works properly.
Steps to reproduce
Use this code to measure coordinates:
comboboxRef.current?.measureInWindow((x, y, width, height) => {
...
})
and mount several similar components at once on the page. The result will be the same for all of them.
Test case
wil provide later if needed
Additional comments
No response
For now workaround is using html element ref for web, provided by findNodeHandle:
measureComboboxLayout: (
callback: (x: number, y: number, width: number, height: number) => void
) => {
if (!comboboxHtmlRef.current) {
return
}
const rect = comboboxHtmlRef.current.getBoundingClientRect()
callback(rect.left, rect.top, rect.width, rect.height)
}
This issue is reproducible for the inverted FlatList
You can try the following code. Without inverted, it looks like working but doesn't work with inverted=true
import React from "react";
import { FlatList, Pressable, StyleSheet, Text, View } from "react-native";
const DATA = [
{
id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
title: 'First Item',
},
{
id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
title: 'Second Item',
},
];
const Item = ({title}) => {
const ref = React.useRef(null);
const [pos, setPos] = React.useState(0);
const onPress = () => {
if (ref.current) {
ref.current.measureInWindow((x,y,w,h) => {
setPos(y);
});
}
};
return (
<Pressable style={styles.item} onPress={onPress} ref={ref}>
<Text style={styles.title}>{title}: {pos}</Text>
</Pressable>
)
};
function App() {
return (
<View style={styles.app}>
<FlatList
data={DATA}
renderItem={({item}) => <Item title={item.title} />}
keyExtractor={item => item.id}
inverted
/>
</View>
);
}
const styles = StyleSheet.create({
app: {
marginHorizontal: "auto",
padding: 16,
maxWidth: 500
},
item: {
backgroundColor: '#f9c2ff',
padding: 20,
marginVertical: 8,
marginHorizontal: 16,
},
title: {
fontSize: 32,
},
});
export default App;