You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When <TrueSheet scrollable={true}> wraps a child <ScrollView>, the ScrollView's content view becomes invisible after any tree-wide React re-render (e.g. theme/appearance change, locale switch) that happens while the sheet is dismissed. On the next present(), the sheet displays normally but the in-flow content inside the ScrollView is missing. Only sibling absolute-positioned views render. A full JS bundle reload restores it.
Visual repro
Step 1: open the sheet (works correctly). Outer View (red bg) + ScrollView (translucent blue overlay = magenta) + hardcoded yellow DEBUG text + real content + sibling absolute-positioned chip/X overlay — all visible.
Step 3 → 4: dismiss sheet, flip theme, re-open. Outer View (red) and ScrollView (blue overlay = magenta) still paint their backgrounds → confirms both containers are full-size and mounted. The absolute-positioned chip ("FITNESS") + X overlay render. But every in-flow child of the ScrollView — including the hardcoded yellow <Text> with hardcoded black background — is gone.
Repro code
functionMySheet(){constsheetRef=useRef<TrueSheet>(null);const{ mode }=useTheme();// any context that propagates to many componentsreturn(<><ButtononPress={()=>sheetRef.current?.present()}title=\"Open\" /><TrueSheetref={sheetRef}detents={[0.65,1]}scrollable={true}><Viewstyle={{flex: 1,backgroundColor: 'red'}}><ScrollViewstyle={{flex: 1,backgroundColor: 'rgba(0,0,255,0.4)'}}><Textstyle={{color: 'yellow',fontSize: 32,backgroundColor: 'black'}}>
HELLO
</Text><Text>Body content here…</Text></ScrollView><Viewstyle={{position: 'absolute',top: 0,left: 0,right: 0}}><Text>This overlay text always renders correctly.</Text></View></View></TrueSheet></>
);
}
No — outer View renders (magenta visible), so the conditional passed
Text color matches background
No — hardcoded yellow text on hardcoded black bg is also invisible
Container collapse to zero height
No — both outer View and ScrollView paint their full backgrounds (visible magenta)
Content off-screen (bad contentOffset)
No — scrolling the empty area reveals nothing
Stale React ScrollView native instance
No — conditionally mounting the entire subtree on a flag (unmount on dismiss, mount fresh on present) does not fix it
TrueSheet's React instance is stale
No — key={mode} on <TrueSheet> to force full React remount of TrueSheet itself also doesn't fix it
The only thing that fixes it short of a JS reload is removing the inner <ScrollView> entirely (rendering content directly into a plain <View>). With that, the same content renders correctly after theme switches every time.
Hypothesis
scrollable={true} appears to install some native-side observation/binding on the inner UIScrollView. After tree-wide re-renders that recreate the inner ScrollView's native view, the binding ends up in a state where the content view stays hidden, even though the JS side reports it mounted. Reload reconstructs the entire native sheet, restoring it.
Note: this app runs on the New Architecture (Fabric). On Fabric, native views can be unmounted/recreated more aggressively during reconciliation than on the old bridge. The bug may be specific to Fabric, or simply easier to trigger there — worth confirming whether old-arch users hit the same symptom.
Workaround
Remove the inner <ScrollView>. Lay content directly into a <View>:
Trade-off: lose in-sheet scrolling for content that overflows the detent height.
Environment
@lodev09/react-native-true-sheet: 3.9.9
react-native: 0.83.6
react: 19.2.0
expo: ~55.0.24
iOS: 16+ deployment target, tested on iOS 17/18
Architecture: New (Fabric) — newArchEnabled: true in app.config.js
Device: iPhone (physical + simulator both reproduce)
Happy to help
If a maintainer can point me at the Swift code that handles the scrollable binding, I'd be happy to attempt a PR — the symptom strongly suggests the observation isn't being torn down + re-established when the underlying UIScrollView is recreated.
Summary
When
<TrueSheet scrollable={true}>wraps a child<ScrollView>, the ScrollView's content view becomes invisible after any tree-wide React re-render (e.g. theme/appearance change, locale switch) that happens while the sheet is dismissed. On the nextpresent(), the sheet displays normally but the in-flow content inside the ScrollView is missing. Only sibling absolute-positioned views render. A full JS bundle reload restores it.Visual repro
Step 1: open the sheet (works correctly). Outer View (red bg) + ScrollView (translucent blue overlay = magenta) + hardcoded yellow DEBUG text + real content + sibling absolute-positioned chip/X overlay — all visible.
Step 3 → 4: dismiss sheet, flip theme, re-open. Outer View (red) and ScrollView (blue overlay = magenta) still paint their backgrounds → confirms both containers are full-size and mounted. The absolute-positioned chip ("FITNESS") + X overlay render. But every in-flow child of the ScrollView — including the hardcoded yellow
<Text>with hardcoded black background — is gone.Repro code
Steps:
JS reload restores correct behavior immediately.
What I've ruled out
key={mode}on<TrueSheet>to force full React remount of TrueSheet itself also doesn't fix itThe only thing that fixes it short of a JS reload is removing the inner
<ScrollView>entirely (rendering content directly into a plain<View>). With that, the same content renders correctly after theme switches every time.Hypothesis
scrollable={true}appears to install some native-side observation/binding on the inner UIScrollView. After tree-wide re-renders that recreate the inner ScrollView's native view, the binding ends up in a state where the content view stays hidden, even though the JS side reports it mounted. Reload reconstructs the entire native sheet, restoring it.Workaround
Remove the inner
<ScrollView>. Lay content directly into a<View>:Trade-off: lose in-sheet scrolling for content that overflows the detent height.
Environment
@lodev09/react-native-true-sheet: 3.9.9react-native: 0.83.6react: 19.2.0expo: ~55.0.24newArchEnabled: truein app.config.jsHappy to help
If a maintainer can point me at the Swift code that handles the scrollable binding, I'd be happy to attempt a PR — the symptom strongly suggests the observation isn't being torn down + re-established when the underlying UIScrollView is recreated.