Majid Lotfinia
Majid Lotfinia

Reputation: 714

React Native FlatList onViewableItemsChanged callback encounter error after state changed rerender

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

enter image description here

Upvotes: 5

Views: 6565

Answers (1)

jQN
jQN

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

Related Questions