diff --git a/src/__tests__/RecyclerView.test.tsx b/src/__tests__/RecyclerView.test.tsx index c01af4834..b97ccde17 100644 --- a/src/__tests__/RecyclerView.test.tsx +++ b/src/__tests__/RecyclerView.test.tsx @@ -162,6 +162,32 @@ describe("RecyclerView", () => { }); }); + describe("Viewability after data updates", () => { + it("reports visible items when data is replaced at the same indices", () => { + const onViewableItemsChanged = jest.fn(); + const result = render( + item.id} + onViewableItemsChanged={onViewableItemsChanged} + viewabilityConfig={{ minimumViewTime: 0 }} + renderItem={({ item }) => {item.id}} + /> + ); + + result.act(() => jest.runAllTimers()); + onViewableItemsChanged.mockClear(); + + result.setProps({ data: [{ id: "b" }] }); + result.act(() => jest.runAllTimers()); + + expect(onViewableItemsChanged).toHaveBeenCalledWith({ + viewableItems: [expect.objectContaining({ item: { id: "b" } })], + changed: [expect.objectContaining({ item: { id: "b" } })], + }); + }); + }); + describe("Item separators in grid mode", () => { const Separator = () => ; diff --git a/src/recyclerview/RecyclerViewManager.ts b/src/recyclerview/RecyclerViewManager.ts index 41704d03e..12ade246f 100644 --- a/src/recyclerview/RecyclerViewManager.ts +++ b/src/recyclerview/RecyclerViewManager.ts @@ -300,6 +300,7 @@ export class RecyclerViewManager { } processDataUpdate() { + this.itemViewabilityManager.clearLastReportedViewableIndices(); if (this.hasLayout()) { this.modifyChildrenLayout([], this.propsRef.data?.length ?? 0); if (this.hasRenderedProgressively && !this.recomputeEngagedIndices()) {