fix: flashlist disappearing items#3600
Merged
Merged
Conversation
Contributor
SDK Size
|
oliverlaz
approved these changes
May 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🎯 Goal
This PR addresses an issue with
MessageFlashListwhere items would disappear (but still keep their layout within the internalScrollView). 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
overflowis present - React Native takes a completely different draw path. If we look at the concrete implementation, we can see the radius distinction:clipRectclipPathSo
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,
borderRadiusalso participates ininsetmath of theView. This essentially means that it creates proper bounds for theCanvasunderneath, should something change.When a
borderis present (and it specifically needs to be aborderwith a knownwidth), we essentially do bounded calculations differently.Namely, here's a breakdown of what's (likely) going on:
overflow !== visiblemakesReactViewGroup.dispatchDrawcallclipToPaddingBox(...)before drawing childrenclipToPaddingBox(...)usescanvas.clipPath(...), notcanvas.clipRect(...)borderWidthremoves the border insets/border drawable layer that had previously participated in this rounded clipping geometry and invalidation pathMessageFlashList, cells are recycled and absolutely repositioned while their content/layout changes and that makes the borderless roundedclipPathstate 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 whichitemtype was being recycled, since single attachments are rendered fully as a bubble)overflow: 'hidden'avoids this native clipping branch entirely, so recycledFlashListcells are no longer dependent on a stale rounded clip pathIn other words, as the
CellRenderergets recycled fromFlashList, its inner children do not know that they need to recalculate and so the newpropsare 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 inFlashListitem descendants we need to make sure that the layout of theViewis 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
MessageContentcomponents are going to go down the easier drawing route.🛠 Implementation details
🎨 UI Changes
iOS
Android
🧪 Testing
☑️ Checklist
developbranch