I'm building UI for my app and I'd like to know the y coordinate of the element that the user clicks on in my FlatList. What causes variables I create in onLayout
not to appear in onPress
, and how can I fix it?
<FlatList
keyExtractor={(item) => item.id}
data={data}
renderItem={({item}) => (
<TouchableOpacity
onLayout={(event) => {
var {x, y, width, height} = event.nativeEvent.layout;
}}
onPress={()=>{console.log(y)}}> //Can't find variable: y
<Text>{item.text}</Text>
</TouchableOpacity>
)}/>
CodePudding user response:
onLayout
is only called on the initial render and if the element changes. The element most likely isn't changing while you're scrolling, so its position on screen isn't measured again.
The best way I know to handle this is to store the ref of the list item, and run its measure
method when it's touched. You can read about measure
here: https://reactnative.dev/docs/direct-manipulation#measurecallback
You'd have to make a new component instead of writing it inline in the FlatList render method, something like:
const ListButton = ({ text, onPress }) => {
const buttonRef = useRef(null);
const onPressWithMeasure = () => {
buttonRef.current?.measure((x, y, width, height, pageX, pageY) => {
console.log(x, y, width, height, pageX, pageY);
onPress();
});
};
return (
<TouchableOpacity onPress={onPressWithMeasure} ref={buttonRef}>
<Text>{text}</Text>
</TouchableOpacity>
);
};
And then in your FlatList:
<FlatList
keyExtractor={(item) => item.id}
data={data}
renderItem={({ item }) => (
<ListButton text={item.text} onPress={() => {}} />
)}
/>