1

I am trying to implement FlatList onViewableItemsChanged using Functional Component. I Want to change state as the user scrolls. Initially, I Wrote This

 const [activeAlphabet,setAlphabet] = useState(0)
    const onViewableItemsChanged =(viewableItems)=> {
            setActiveAlphabet(viewableItems.viewableItems[0].index)
        }
    const viewConfigRef = { viewAreaCoveragePercentThreshold: 50 }
    <FlatList
        keyExtractor={(item, index) => index.toString()}
        data={Object.entries(cat)}
        onViewableItemsChanged={viewableItems => onViewableItemsChanged(viewableItems)}
        viewabilityConfig={viewConfigRef}
        renderItem={({ item,index }) =>.......}
        />

But I was getting a error

Invariant Violation: Changing onViewableItemsChanged on the fly is not supported

FlatList ScrollView Error on any State Change - Invariant Violation: Changing onViewableItemsChanged on the fly is not supported

This Answer Suggests using useRef to solve the issue So, I changed the code to this.

const [activeAlphabet,setActiveAlphabet] = useState(0)
   const onViewableItemsChanged =useRef((viewableItems)=> {
        setActiveAlphabet(viewableItems.viewableItems[0].index)
    })
    console.log(onViewableItemsChanged)
    const viewConfigRef = useRef({ viewAreaCoveragePercentThreshold: 50 })
    <FlatList
        keyExtractor={(item, index) => index.toString()}
        data={Object.entries(cat)}
        onViewableItemsChanged={onViewableItemsChanged.current}
        viewabilityConfig={viewConfigRef.current}
        renderItem={({ item,index }) =>.......}
        />

But Now the problem is

setActiveAlphabet(viewableItems.viewableItems[0].index)

is not working, it has no effect.

1 Answers1

0

you need to do this with useRef , useState will render the component and onViewableItemsChanged does not support instant change, take reference from below code.

  const ref = useRef(null);

          <FlatList
            ref={ref}
            horizontal={true}
            data={images}
            initialNumToRender={5}
            showsHorizontalScrollIndicator={false}
            keyExtractor={keyExtractor}
            snapToInterval={Metrics.screenWidth}
            snapToAlignment={'center'}
            decelerationRate={'fast'}
            viewabilityConfig={{
              itemVisiblePercentThreshold: 50,
             }}
            onViewableItemsChanged={onViewableItemsChanged}
            renderItem={renderImageItem}
          />

    const onViewableItemsChanged = useCallback(({viewableItems}) => {
      console.log('viewableItems data', viewableItems);
        selectedImageHandler(viewableItems[0].index);
        ref.current.scrollToIndex({
          index: viewableItems[0]?.index,
          viewOffset: Metrics.scale(25),
        });
    }, []);
Syed Amir Ali
  • 873
  • 12
  • 22