# Why does an Android bottom sheet disappear inside a clipped FlatList row?

> Use the issue’s row-position clues to test Android list clipping, modal-host lifetime, and Expo version boundaries without treating an unverified report as a fix.
> By Dave · 2026-10-24
> Source: https://otf-kit.dev/blog/expo-android-bottom-sheet-flatlist-clipping

If an Android bottom sheet stops opening from one `FlatList` row, first check whether the sheet host is mounted inside a row that Android clips. The current Expo issue is a reporter's diagnosis, not a maintainer-confirmed cause, so reproduce it before treating clipping as the fix.

If you are comparing reusable app foundations, review the [OTF Everything Bundle](https://otf-kit.dev/pricing#bundle) or the [free native SDK](https://github.com/otf-kit/sdk). Neither includes this SDK 58 bottom-sheet fix. Arcade is only an Expo game-store browse/detail-flow reference: its kit uses SDK 54, and it does not contain the issue's reproduction.

## What the report actually shows

An open Expo issue describes a narrow failure in `@expo/ui/community/bottom-sheet` on Android. In the reporter's reproduction, tapping the first list item did not present its modal. A second tap produced an unhandled rejection about a missing `partialExpand` handler. A row fully inside the viewport worked, while a row with its top edge clipped above the viewport failed. The report names Expo SDK 58.0.17, React Native 0.88.0, and `@expo/ui` 58.0.22.

That sequence is more useful than the title alone. It gives a controlled comparison: one row near a clipping boundary fails; another row fully visible succeeds. But the issue has not been verified by an Expo maintainer, and its test device is unspecified. The failure is evidence to investigate, not proof that every Android list or bottom sheet behaves this way.

The reporter's theory is that an inline native host gets detached when `FlatList` clips the row. The reporter points to an absolute-positioned, zero-height host and Android's `removeClippedSubviews` behavior. That explanation is plausible given the symptoms, but it remains the issue author's source-level interpretation. Keep the distinction clear in debugging notes: the taps and exception are reported observations; host detachment is the proposed mechanism.

## Why the first row can be a useful clue

`FlatList` virtualizes rows so it can avoid keeping every native view mounted at once. React Native documents `removeClippedSubviews` as a performance option that removes offscreen child views from their native backing superview. The docs also warn that it can lead to missing content in some circumstances, and say the default is `true` on Android.

That does not mean clipping is necessarily the root cause in this issue. A row can be visually present while a zero-size or separately hosted native child is outside the list's clipping bounds. A modal component may also have asynchronous native registration that does not line up with the JavaScript state change. Several lifecycle boundaries can produce a similar symptom, so a single failing tap is not enough to identify one.

The first row is worth comparing because it often sits at the start of the list's viewport, where a host at the same coordinate may interact differently with clipping than a host in a fully visible row. The report also says that scrolling a little so the row's top edge is clipped reproduces the failure. Treat those as reproduction clues from this one issue, not as a universal rule about row zero.

![Two list rows compared at the clipping boundary: the fully visible row presents a sheet, while the clipped row does not.](https://cdn.otf-kit.dev/blog/expo-android-bottom-sheet-flatlist-clipping/inbody1-boundary-clue-20261024-ar2.png?v=20261024-b)

## Reproduce before changing the list

Start with the issue's minimal reproduction or a small screen that contains only a few rows and one sheet trigger. Record the exact package versions, Expo SDK, Android version, build type, and row position. The report says it used a development build, not Expo Go; matching that environment matters because the component uses native platform code.

Run the same sequence against a row fully inside the viewport and one whose top edge is clipped. Tap once, then again, and capture the first native or JavaScript error. If the failure moves with the row position, that supports investigating a layout or clipping boundary. It still does not establish the mechanism. Also test after the row remounts and after navigating away and back, because those actions can change native registration and component lifetime.

For diagnosis, temporarily set `removeClippedSubviews={false}` on the list and repeat the exact sequence. A change in behavior would make clipping a stronger suspect. It is a diagnostic comparison, not an automatic production fix: disabling clipping may affect memory use and scroll performance, and the test does not explain whether the bottom-sheet host or another child is being detached. Restore the original setting after the check, and keep the result with the issue's environment details.

## Put modal lifetime above row lifetime

If a sheet represents a selected item, a safer structure to test is to keep one sheet at the screen level and store the selected item in screen state. A row selects an item; the screen-level sheet presents that selection. The sheet then does not mount and unmount with each virtualized row.

The issue reporter describes a portal mounted at the app root as a workaround. Verify that pattern in the exact library and Expo version you ship before adopting it. A portal changes where the host is rendered; it does not prove that the original issue is fixed upstream or that every modal implementation needs a portal.

Also keep UI state aligned with native state. If JavaScript marks a sheet open before the native view can handle the open call, a rejected native command can leave the app believing the sheet is open when nothing is visible. Handle rejected presentation calls, avoid optimistic state that cannot recover, and make a retry or close path possible. These are defensive design ideas, not confirmed fixes for issue #52091.

![A screen-level modal host is shown as an option to test above row-owned hosts whose lifetime follows virtualized list cells.](https://cdn.otf-kit.dev/blog/expo-android-bottom-sheet-flatlist-clipping/inbody2-safer-host-lifetime-20261024-ar2.png?v=20261024-c)

## Check the library boundary before choosing a starter

The current Expo UI documentation describes a bottom-sheet API built on native modal presentation on Android and iOS, with web using an HTML dialog. The reported issue is narrower: a community bottom-sheet component inside a clipped list row on Android. Do not generalize it to every Expo sheet API, every platform, or every SDK release.

The Arcade Kit is a browse-first games showcase built on Expo SDK 54. Its page documents home, browse, store, search, and game-detail flows. It does not claim to use the SDK 58 `@expo/ui` community bottom sheet discussed here, and it does not include this issue's reproduction. If a games product needs a list-to-detail sheet, treat this as an extension decision to test in your own target SDK, not a kit feature or a kit bug.

Before buying any Expo starter, inspect the actual version and screen flows you plan to extend. Confirm whether a required native component is already present, whether its API matches your target SDK, and whether its host belongs at screen level or inside a virtualized cell. A starter can provide the surrounding browse/detail structure; your team still owns the component choice, integration, and Android verification.

## A short decision checklist

1. Reproduce on the same Expo, React Native, and component versions as the failing app.
2. Compare a fully visible row with a clipped row and capture the first failing native call.
3. Toggle clipping only as a temporary diagnostic, then restore the original setting.
4. If the sheet is modal for a screen, test a screen-level host or a documented portal pattern.
5. Keep the issue's workaround separate from an upstream fix until a maintainer verifies the behavior.
6. Re-run the list-to-sheet flow on the Android versions and build types your release supports.

That process keeps the investigation proportional. It tells you whether the failure follows row geometry, component lifetime, or a package/version boundary without claiming more than the available evidence supports.

## Sources

Updated 24 October 2026.

- Expo issue #52091, opened 22 October 2026: https://github.com/expo/expo/issues/52091. The issue remains open; its bot assessment says the behavior has not been verified. The reproduction, environment, and root-host/portal theory are reported by the issue author.
- React Native documentation, “FlatList”: `removeClippedSubviews` behavior, missing-content warning, and Android default.
- Expo documentation, “BottomSheet”: current Expo UI API and platform presentation; it does not confirm the reported issue or workaround.
- [Arcade Kit page](https://otf-kit.dev/templates/arcade-kit). Confirms the kit's SDK 54 game-store browse/detail scope.
- Related OTF article, [“Buy the Arcade kit when the product is a games store”](https://otf-kit.dev/blog/buy-arcade-kit-games-store).