NativeStackNavigator - cannot call navigate in useEffect on iOS
See original GitHub issueHello,
I’m trying to fetch data when app is started and based on response I would like to show Modal to the user.
My modal screen is presented in RootNavigator, which is defined as NativeStackNavigator (import {createNativeStackNavigator} from 'react-native-screens/native-stack'
) and code looks like:
import React from 'react';
...
const Stack = createNativeStackNavigator<RootStackParams>();
const MAIN_STACK_PROPS = {
stackPresentation: 'modal' as const,
headerShown: false,
contentStyle: {
backgroundColor: colors.background,
zIndex: 50000,
},
};
const ALERT_MODAL_OPTIONS = {
stackPresentation: 'transparentModal' as const,
stackAnimation: 'fade' as const,
contentStyle: {
backgroundColor: 'rgba(0,0,0,0.8)',
},
};
const RootStack = () => {
return (
<NavigationContainer ref={navigationRef}>
<SafeAreaProvider>
<ErrorBoundary>
<Stack.Navigator
initialRouteName="Main"
screenOptions={MAIN_STACK_PROPS}>
<Stack.Screen name="Main" component={TabNavigator} />
<Stack.Screen
name="DownloadModal"
component={DownloadModal}
options={ALERT_MODAL_OPTIONS}
/>
</Stack.Navigator>
</ErrorBoundary>
</SafeAreaProvider>
</NavigationContainer>
);
};
export default RootStack;
My Home screen Inside NativeStackNavigator (RootStack) -> BottomTabNavigator (TabNaigator) -> StackNavigator
then contains a custom react hook, which performs fetch action in it’s useEffect and simplified example looks like:
React.useEffect(() => {
const data = fetchData();
if (data) {
navigation.navigate('DownloadVideoModal', {
data
});
}
}, [])
In this example, I’m getting navigation
prop using useNavigation()
from React Navigation.
The problem is that new screen (DownloadModal) is not VISIBLE. I said visible on purpose, because at this point I cannot see a new screen is pushed but I’m also not able to trigger any other screen from RootStack using navigation.navigate() function. It looks like my whole RootStack is stucked at this point (However, nested navigators works just fine).
Navigate function is working even when I refresh the app (CMD + R
). It is not working only after app is fresh-started.
However, if I tried to change my RootStack to use StackNavigator (from React Navigation lib) instead of NativeStackNavigator, then everything works correctly.
Do you have any suggestion how to overcome this problem? If you need repro, I will try to create one later.
BTW: I also tried to use navigationRef from Navigating without the navigation prop guide and I’ve also tried to implement on onReady
callback on NavigationContainer
but without any success.
I’m able to overcome this issue using setTimeout
with long enough delay but I think that it is an ugly hack. Hack that helped looks like:
React.useEffect(() => {
const data = fetchData();
if (data) {
setTimeout(() => {
navigation.navigate('DownloadVideoModal', {
data
});
}, 3500);
}
}, [])
Thank you for any help!
react-native: 0.62.2
react-navigation/bottom-tabs: 5.7.3
react-navigation/native: 5.7.2
react-navigation/stack: 5.8.0
react-native-screens: 2.9.0
Issue Analytics
- State:
- Created 3 years ago
- Comments:12 (3 by maintainers)
Top GitHub Comments
Hi @Pat-Gekoski Developing with
react-navigation
differs a bit from what we used to do in “normal” React. Screens in astack
are never really unmounted. So when a screen “mounts” once again it has no real effect on the navigation. React navigation team overcome that problem by introducing afocus
event, which is called when the screen comes into focus.This part of the documentation explains the lifecycle of navigation in detail and I highly recommend checking it out. It’ll save you a lot of time 😅
Also, your code has nothing to do with
react-native-screens
. We are the creators ofnative-stack
. All of the other navigators are made byreact-navigation
team fyi 😄The above listener seems to work, but how come the provided
useFocusEffect
hook doesn’t: