Skip to content

fix: flashlist disappearing items#3600

Merged
isekovanic merged 2 commits into
developfrom
fix/flash-list-disappearing-items
May 18, 2026
Merged

fix: flashlist disappearing items#3600
isekovanic merged 2 commits into
developfrom
fix/flash-list-disappearing-items

Conversation

@isekovanic
Copy link
Copy Markdown
Contributor

🎯 Goal

This PR addresses an issue with MessageFlashList where items would disappear (but still keep their layout within the internal ScrollView). The reason behind it is quite technical and it was pretty difficult to find, even though it's just a oneliner.

The PR that introduced this was this one specifically.

Typically, when overflow is present - React Native takes a completely different draw path. If we look at the concrete implementation, we can see the radius distinction:

  • no rounded borders: clipRect
  • rounded borders: clipPath

So borderRadius + overflow: 'hidden' forces the more complex rounded path clipping branch (in other words meaning, instead of drawing a rectangle with discrete dimensions; draw an oval shape instead).

Now, borderRadius also participates in inset math of the View. This essentially means that it creates proper bounds for the Canvas underneath, should something change.

When a border is present (and it specifically needs to be a border with a known width), we essentially do bounded calculations differently.

Namely, here's a breakdown of what's (likely) going on:

  1. overflow !== visible makes ReactViewGroup.dispatchDraw call clipToPaddingBox(...) before drawing children
  2. Because the view has rounded borders, clipToPaddingBox(...) uses canvas.clipPath(...), not canvas.clipRect(...)
  3. That rounded clipping path is computed from the view bounds, border radius and border insets
  4. Removing borderWidth removes the border insets/border drawable layer that had previously participated in this rounded clipping geometry and invalidation path
  5. Enter MessageFlashList, cells are recycled and absolutely repositioned while their content/layout changes and that makes the borderless rounded clipPath state fragile on Android: the row could remain mounted, measured and pressable, while the draw pass clipped some or all descendants out (this is why the bug represented either thorough an empty message bubble or a completely gone one, depending on which item type was being recycled, since single attachments are rendered fully as a bubble)
  6. Removing overflow: 'hidden' avoids this native clipping branch entirely, so recycled FlashList cells are no longer dependent on a stale rounded clip path

In other words, as the CellRenderer gets recycled from FlashList, its inner children do not know that they need to recalculate and so the new props are injected into a view which cannot display them and we either get the full bubble missing or the content not being there in text messages specifically.

Very interesting nonetheless. Also probably something important to keep in mind for the future. If we are ever to use overflow: 'hidden' specifically in FlashList item descendants we need to make sure that the layout of the View is fully stable and measureable, so that recycling does not accidentally skip necessary recalculations.

Also, ironically, this should also be a slight performance improvement as well (at least on Android) as now all MessageContent components are going to go down the easier drawing route.

🛠 Implementation details

🎨 UI Changes

iOS
Before After
Android
Before After

🧪 Testing

☑️ Checklist

  • I have signed the Stream CLA (required)
  • PR targets the develop branch
  • Documentation is updated
  • New code is tested in main example apps, including all possible scenarios
    • SampleApp iOS and Android
    • Expo iOS and Android

@isekovanic isekovanic requested review from oliverlaz and szuperaz May 16, 2026 11:41
@Stream-SDK-Bot
Copy link
Copy Markdown
Contributor

Stream-SDK-Bot commented May 16, 2026

SDK Size

title develop branch diff status
js_bundle_size 368 KB 368 KB 0 B 🟢

@isekovanic isekovanic merged commit daf6e29 into develop May 18, 2026
5 checks passed
@isekovanic isekovanic deleted the fix/flash-list-disappearing-items branch May 18, 2026 10:40
@github-actions github-actions Bot mentioned this pull request May 19, 2026
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants