Reputation: 714
I need to set the state to detect which item in the current viewport is visible. for this purpose, I write below code:
const [inViewPort, setInViewPort] = useState(0);
const viewabilityConfig = {
viewAreaCoveragePercentThreshold: 30,
};
const onViewableItemsChanged = ({viewableItems, changed}) => {
if (changed && changed.length > 0) {
setInViewPort(changed[0].index);
}
};
return (
<SafeAreaView style={styles.container}>
<FlatList
data={myData}
renderItem={renderItem}
showsHorizontalScrollIndicator={false}
keyExtractor={(_, index) => index.toString()}
horizontal={true}
onViewableItemsChanged={onViewableItemsChanged}
viewabilityConfig={viewabilityConfig}
/>
</SafeAreaView>
);
The onViewableItemsChanged event callback triggers correctly but after I call setInViewPort so the component updated and it rerendered the below error encounter:
Invariant Violation: Changing onViewableItemsChanged on the fly is not supported
Upvotes: 5
Views: 6565
Reputation: 609
I was looking for the same answer and there is no clear example anywhere. This is how I solved it.
const [inViewPort, setInViewPort] = useState(0)
const viewabilityConfig = useRef({
itemVisiblePercentThreshold: 50,
waitForInteraction: true,
minimumViewTime: 5,
})
const onViewableItemsChanged = React.useRef(({ viewableItems, changed }) => {
if (changed && changed.length > 0) {
setInViewPort(changed[0].index);
}
})
return (
<SafeAreaView style={styles.container}>
<FlatList
data={myData}
renderItem={renderItem}
showsHorizontalScrollIndicator={false}
keyExtractor={(_, index) => index.toString()}
horizontal={true}
onViewableItemsChanged={onViewableItemsChanged.current}
viewabilityConfig={viewabilityConfig.current}
/>
</SafeAreaView>
)
Upvotes: 8