flash-list: ViewableItems not working with FlashList

With FlatList and react-native-big-list the ViewableItems works fine but with FlashList does’t works

When the items change the FlashList it’s not passing the new state to Component inside of the renderItem

How can I fix It ?

This is a Android APP expo 46 and Expo GO

const onViewRef = React.useRef(({ viewableItems, changed }) => {
    if (viewableItems && viewableItems.length > 0) {
      setItemState(viewableItems[0]);
    }
  });

  const viewConfigRef = React.useRef({
    viewAreaCoveragePercentThreshold: 50,
  });

 const keyExtractor = useCallback(
    (item, index) => `${item.hash}${index}${item.post_id}`,
    []
  );

  const renderItemFinal = ({ item, index }) => {
    if (item?.post_type == "video") {
      return (
        <Video
          patrocinado={item?.patrocinado}
          index={index * page}
          userStorage={userStorage}
          postUnlike={postUnlike}
          postLike={postLike}
          onViewRef={
            itemState?.item?.post_id == item?.post_id && itemState?.isViewable
              ? true
              : false
          }
          item={item}
        />
      );
    }
  };

 const itemRender= useMemo(() => renderItemFinal, [itemState]);


 <FlashList
    refreshControl={refreshingjsx}
    data={videos}
    onEndReachedThreshold={0.2}
    onEndReached={reachedJsx}
    renderItem={itemRender}
    onViewableItemsChanged={onViewRef.current}
    viewabilityConfig={viewConfigRef.current}
    keyExtractor={keyExtractor}
    snapToAlignment={"start"}
    decelerationRate={"fast"}
    snapToInterval={win.height}
    itemHeight={win.height}
    estimatedItemSize={100}
/>

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 5
  • Comments: 24 (8 by maintainers)

Most upvoted comments

I can tell you that extraData or data have no effect on this issue. The handler runs fine when viewability changes due to user interaction, but if the data causes the list to re-render, and this affects viewable items, the handler does not fire.

My list re-renders fine. The item itself renders. The onViewableItemsChanged handler does not always fire. I’ve seen it fire sometimes, but many times it doesn’t.

@naqvitalha this would explain the issue we once tried to bugfix (videos not firing play/stop when data changes) Also ping @intergalacticspacehighway

I was able to fix this issue though, at least for my app. We changed our keyExtractor form item id to index and that worked out pretty well for us.

I can tell you that extraData or data have no effect on this issue. The handler runs fine when viewability changes due to user interaction, but if the data causes the list to re-render, and this affects viewable items, the handler does not fire.

My list re-renders fine. The item itself renders. The onViewableItemsChanged handler does not always fire. I’ve seen it fire sometimes, but many times it doesn’t.

I can tell you that Viewability works absolutely fine with FlashList. I am using it in production apps on huge lists. The issues I’ve came across have been the use of state inside my children and the way I’ve kept track of my refs. You need to make sure to react to changes within useEffect when using state in your items or use a smarter way, like context to react to visibility inside your items (starting/stopping videos is exactly what I am doing)

I’d recommend you this Gist by @intergalacticspacehighway https://gist.github.com/intergalacticspacehighway/02a36b05b2236bc750a065833b71c94a

I’ve ported his approach to FlashList within 5 minutes and its actually the most performant way to react to visibility changes.

Could you please provide your flashlist implementation for this gist? Thanks

Yes, because those lists you’ve been working with are not recycling. You need to understand that when you recycle views, you need to take care of some circumstances, like stale state (when you are working with state).

If you wan’t help, setup up a repro with Snack and I can help you out.

I’ll give up. Have fun with FlatList.

I had a similar issue and tried this out by using extraData. but when it comes to updating any state I get an infinite rerender. Any suggestions on how I can perhaps overcome that?

@brunolcarlos did you manage to find a solution?

@brunolcarlos the incomplete code is making debugging this harder but if I have to guess, it’s probably because FlashList doesn’t update all the items unless your data or extraData change. If there’s additional prop rendering depends on, pass it as extraData.

Hi, I don’t need to update the array list, I only update the child when is on viewport and pass a prop to child with true or false. This app is like the Instagram reels, when the video is on viewport I play the video and stop when is not on viewport.

The Component Video doesn’t receive this new information with the flashlist but receive with FlatList.