Repository navigation
ScrollView as child of Modal no longer scrollable on first mount/modal opening, RN >= 0.76, Android only, old-arch only #48822
Description
Activity
- addedPlatform: AndroidAndroid applications.Android applications.
on Jan 21, 2025 - changed the title
[-]ScrollView as child of Modal no longer scrolls on first mount/modal opening, RN >= 0.76, Android only, old-arch only[/-][+]ScrollView as child of Modal no longer scrollable on first mount/modal opening, RN >= 0.76, Android only, old-arch only[/+]on Jan 21, 2025 I also tried reproducing this issue on latest version v0.77.0 it is happening on android old arch, looks like a valid issue
Reacted by David Goguen and Vinícius FigueiroaI'm not sure of the exact internals for this one, but I have a feeling it's something to do with height of the parent view (or height of the ScrollView itself?) not being calculated properly anymore on mount.
+1
+1
Thanks for reporting this and for the great reproduction steps. This just bit us too, this exact scenario. Our workaround was to add
style={{height: 100}}to the ScrollView inside the Modal. Setting flex:1 didn't fix it. For some reason that I don't quite understand, the height of 100px is ignored and it is actually full screen which is what we wanted. But setting height:100 made the scrolling work.We will be switching to the new architecture soon so hopefully this is a temporary hack, or hopefully this issue can get resolved.
Reacted by ChenBr, phil-cef, jibeleck, mikerogerz, Ivan Harelik, Bogdan Nosovytskyy and Biện Thanh NhựtReacted by David GoguenThanks for reporting this and for the great reproduction steps. This just bit us too, this exact scenario. Our workaround was to add
style={{height: 100}}to the ScrollView inside the Modal. Setting flex:1 didn't fix it. For some reason that I don't quite understand, the height of 100px is ignored and it is actually full screen which is what we wanted. But setting height:100 made the scrolling work.We will be switching to the new architecture soon so hopefully this is a temporary hack, or hopefully this issue can get resolved.
This workaround concerns me a bit, just on the off chance the renderer does interpret the height correctly and tries to make the ScrollView only 100px.
BUT, you got me thinking and inspired another workaround. Conditionally render {flex: 1} on the ScrollView after render and a short timeout:
export default function ScrollableModalContent() { const [rendered, setRendered] = React.useState(false); React.useEffect(() => { setTimeout(() => { setRendered(true); }, 200); }, []); return ( <View style={styles.main}> <ScrollView style={rendered ? {flex: 1} : undefined}> <Text>{LOREM_IPSUM}</Text> </ScrollView> </View> ); }This seems to consistently produce the behavior we want, and the 200ms delay of unscrollable content isn't noticeable.
Something tells me this issue is very low priority, affecting the old architecture only.
Ideally I think it's best for people to just switch to the new architecture if they can. In our case, we're just waiting for one of the major libraries we use to catch up with full support for the new architecture, since it doesn't seem to work well with the interop layer.
Reacted by Ibtisam IqbalReacted by Julius Stenbæk ChristoffersenI've got this problem on new arch too.
We have a native framework for iOS. After some scrolls, it gets disabled. While debugging the view, we discovered strange behaviour: React Native (RN) simply sets userInteractionEnabled = false on the scrollView object. However, we are still researching why this happens.
Reacted by wicak and lee@cuong666🐛 Fix: ScrollView Not Rendering in Android Build
@goguda I found a workaround that resolves the issue.
The problem with
ScrollViewnot rendering properly in Android release builds (both old and new architecture) can be resolved by adding a small delay before rendering the scrollable content.✅ Solution
Wrap the
ScrollViewwith aLazyRendercomponent that delays rendering by 50–100ms.// LazyRender.tsx const LazyRender: React.FC<{ children: React.ReactNode; delay: number; }> = ({ children, delay }) => { const [render, setRender] = useState(false); useEffect(() => { const timer = setTimeout(() => setRender(true), delay); return () => clearTimeout(timer); }, [delay]); return render ? <>{children}</> : null; }; export default LazyRender;
Usage:
<LazyRender delay={50}> <ScrollView> {/* scrollable content here */} </ScrollView> </LazyRender>
💡 Credit
Inspired by va-mobile-app PR #10809
Reacted by Ally Burns, Khethelo, Vijay Chouhan, Mathias Tambjerg Steengaard and Hendri PretoriusReacted by David Goguen and KhetheloNice, this does work as well.
Has anyone else been able to confirm that this happens on new architecture as well? I haven't been able to reproduce it on the new architecture myself.
If this does happen on new architecture, I think the title needs to be updated and this bug prioritized.
Reacted by Ally BurnsIf you are still having issues getting a ScrollView to scroll inside a Modal (from react-native) on Android while it works on IOS, try follow this way of implementing it. I have been struggling for two days with this, until I came across this example usage of Modal on the React- Native docs.
Reacted by Szymon KonopekReacted by Szymon KonopekIf you are still having issues getting a ScrollView to scroll inside a Modal (from react-native) on Android while it works on IOS, try follow this way of implementing it. I have been struggling for two days with this, until I came across this example usage of Modal on the React- Native docs.
@Jamiil1620 does wrapping the modal with safe area fix the scrollview issue without the LazyRender solution provided above or did you use both LazyRender and safe area?
@Jamiil1620 does wrapping the modal with safe area fix the scrollview issue without the LazyRender solution provided above or did you use both LazyRender and safe area?
@Santhosh-arch wrapping the modal with SafeAreaProvider and SafeAreaView will suffice. That's what I did and it is working.
Reacted by Szymon KonopekThe following workaround worked for me
Add
const [contentOffset, setContentOffset] = useState(0); useEffect(() => { setTimeout(() => { setContentOffset(1); }); }, []); // .... return ( // ... <Modal animationType="none" transparent={true} visible={true} onRequestClose={() => null}> <ScrollView contentOffset={{ y: contentOffset, x: 0 }} // <<-- this line // ... > {...scrollContent} </ScrollView> </Modal> );
I think the solution right now is to force the state change.
the LazyRender component worked correctly even when the delay was set to 0.
let’s assume you're using the following code inside a modal:
const LazyRender = ({ children, delay }: { children: React.ReactNode; delay: number }) => { const [render, setRender] = useState(false); useEffect(() => { const timer = setTimeout(() => setRender(true), delay); return () => clearTimeout(timer); }, [delay]); return render ? <>{children}</> : null; };
Case A
<ScrollView style={{ heigt: 2000 }} />
Case B
<LazyRender delay={0}> <ScrollView style={{ heigt: 2000 }} /> </LazyRender>
Only Case B worked.
Now, let’s simplify the LazyRender code:
const LazyRender = ({ children }: { children: React.ReactNode }) => { const [render, setRender] = useState(false); useEffect(() => { setRender(true); }, []); return render ? <>{children}</> : null; };
<LazyRender> <ScrollView style={{ heigt: 2000 }} /> </LazyRender>
This also works correctly.
If you didn’t write the code inside a modal exactly like the example but it still works for you, make sure to check whether a state change is happening right when the modal opens.
const CustomScrollView = () => { const [test, setTest] = useState(false); useEffect(() => { setTest(true) }, []) return <ScrollView style={{height:2000}} /> }
<Modal> <CustomScrollView /> </Modal>
or just add height: 0
<Modal> <View style={{ height: 0 }}> <ScrollView /> </View> </Modal>
I don't know why it works when you put height 0, but it works anyway.
problem is same with react-native-modal.
react-native: 0.76
android 15Reacted by Hendri PretoriusIf you are still having issues getting a ScrollView to scroll inside a Modal (from react-native) on Android while it works on IOS, try follow this way of implementing it. I have been struggling for two days with this, until I came across this example usage of Modal on the React- Native docs.
This one actually worked for me
This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.
- addedStaleThere has been a lack of activity on this issue and it may be closed soon.There has been a lack of activity on this issue and it may be closed soon.and removedStaleThere has been a lack of activity on this issue and it may be closed soon.There has been a lack of activity on this issue and it may be closed soon.
on Aug 13, 2026
Description
Since React Native 0.76.0, a ScrollView as a child of the built-in Modal component is no longer scrollable when the modal first opens on Android.
This seems to only affect the old architecture. New architecture seems to be unaffected.
iOS seems unaffected.
The problem is still present in RN 0.77. Downgrading to 0.75.4 fixes it.
Steps to reproduce
yarn android. The reproduction is set to use the old architecture by default.Open Scrollable Modalbutton.ScrollableModalContent.tsxby adding astyle={{flex: 1}}to the ScrollView and saving the file. This hot-reloads the component without unmounting at the parent, and suddenly the ScrollView becomes scrollable.style={{flex: 1}}still on the ScrollView.style={{flex: 1}}from the ScrollView and save the file.gradle.properties.React Native Version
0.77.0
Affected Platforms
Runtime - Android
Output of
npx react-native infoStacktrace or Logs
Reproducer
https://github.com/goguda/react-native-android-scrollview-in-modal-not-always-scrolling-point-76-up
Screenshots and Videos
No response