how to display the initial screen when navigating between navigators - react-native

I have a TabNavigator and a StackNavigator. I made a RootStackNavigator to navigate between the two navigators:
<RootStack.Screen
name="AddOrderNavigator"
component={AddOrderNavigator}
options={{ animationEnabled: true, gestureEnabled: false, headerLeft: null }}
/>
<RootStack.Screen
name="App"
component={AppNavigator}
options={{ animationEnabled: true, gestureEnabled: false, headerLeft: null }}
/>
All works good, except when I navigate from one to another; it doesn't display the initial screen, it keeps the old state and displays the screen I was in before I go to the other.
Edit:
So the solution was to specify the screen I wanted to navigate to:
navigation.push("AddOrderNavigator", {screen: 'DeliveryTypeScreen'});

Related

React-Native Tab Navigation drawer navigation how to hide tabbar and header for every screen v6

Trying to hide header and tabbar in Tab navigation in v6
<Tab.Screen
name="LoginScreens"
component={LoginStackScreen}
options={{tabBarVisible: false}}
/>
But here tabBarVisible is not working
After researching found the solution which is different from v5
<Tab.Navigator
screenOptions={{
headerShown: false,
}}>
<Tab.Screen
name="LoginScreens"
component={LoginStackScreen}
options={{
tabBarStyle: {display: 'none'},
}}
/>
</Tab.Navigator>
tabBarStyle: {display: 'none'} to hide the tabbar and headerShown: false is to hide the header for all pages

Changing navigation animation direction in react-native?

I'm currently working on a mobile application written in react-native.
This project has a number of different screens all of which are configured with createStackNavigator.
I need to be able to change the animation direction on the fly. I could be navigating to the same page on different parts of the app but require different animations. (by animation I means the direction the current screen exits the view)
I am aware options can be passed to the screen when defined to set the navigation direction. This is unfortunately no use to me as the animation may change from page to page.
Example screen declaration from my project (names have been sanitised):
<NavigationContainer ref={navigationRef}>
<Stack.Navigator initialRouteName={initialRoute}>
<Stack.Screen name="screen1" component={screen1} options={{headerShown: false, gestureEnabled: false}} />
<Stack.Screen name="screen2" component={screen2} options={{headerShown: false, gestureEnabled: false}} />
<Stack.Screen name="screen3" component={screen3} options={{headerShown: false, gestureEnabled: false}} />
<Stack.Screen name="screen4" component={screen4} options={{headerShown: false, gestureEnabled: false}} />
</Stack.Navigator>
</NavigationContainer>
Example navigation reset:
navigation.reset({
index: 0,
routes: [{ name: "screen1", params: { param1: 'paramStrData' } }]
});
Example navigation replace:
navigation.replace('screen2', { param1: 'param1StrData'})
Ideally, I'd like to be able to pass a navigation animation direction to the replace or reset functions.
Is this at all possible?
Thanks again in advance.
add props persentation , animationTypeForReplace , animation like this.
<Stack.Screen
name="screen1"
component={screen1}
options={{
headerShown: false,
presentation: 'modal',
animationTypeForReplace: 'push',
animation:'slide_from_right'
}}
/>
Pass animation,presentation and animationTypeForReplace props inside options
example.
<Stack.Screen
name="screen"
component={screen}
options={{
headerShown: false,
presentation: 'modal',
animationTypeForReplace: 'push',
animation:'slide_from_right'
}}
/>
Both answers above contributed to a solution in some way.
My understanding of the navigation stack was a little flawed at this time.
We can't dynamically change the animation type - i.e. swipe left or right.
The animation type is selected based on where the new screen is on the navigation stack or not. If already on the stack, the current screen will exit to the right and the new (previous) screen will enter from the left - this is to simulate going back.
If the new screen is not on the navigation stack, the new screen will enter from the right to simulate adding a new screen to the navigation stack.
naviagation.navigate('screenName', {param1: 'p1', param2: 'p2'})
navigate needs to be used opposed to replace to make this work.
Hope this helps someone at some point as this was something I struggled to understand for some time.

How can I hide the screen header but show my back button?

I would like to hide my screen header but still show the back button in my Stack Navigator? I have set screenOptions={{ headerShown: false }} in my Stack.Navigator, which hides both the screen header and back button. I would like to just hide the screen header.
Can someone please assist with this? Below is my Stack Navigator:
function SearchStack() {
return (
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="SearchScreen" component={SearchScreen} />
<Stack.Screen name="SearchListScreen" component={SearchListScreen} />
</Stack.Navigator>
);
}
In the tab navigator the stack is set as:
<Tab.Navigator screenOptions={({ route }) => ({
tabBarIcon: ({ focused, color, size }) => {...})}>
<Tab.Screen name="Search" component={SearchStack} />
</Tab.Navigator>
This is what I'm currently seeing:
But this is what I would like to have with my Tab navigation bar still at the bottom for the search stack:
This is what I get using options={{headerMode:"none"}} in Stack.Navigator:
The below occurs when adding updating the Stack.Navigator to <Stack.Navigator screenOptions={{ headerTitle:"", headerTransparent:true }}> . How can add or move the back button to the top exactly like the 2nd image, which is achieved when not adding the Stack to the Tab.Screen so changing:
<Tab.Screen name="Search" component={SearchStack} />
to
<Tab.Screen name="Search" component={SearchScreen} />
but doing this causes the tab to not appear in the Search list screen.
The back button is part of the header, so you can't hide the header and keep the back button.
What you want to do is to hide other parts of the header except for the back button, which would be
Title, with headerTitle: ""
Background, with headerTransparent: true
for hide the back button in react-native, we can use property,
headerBackVisible:false this property only work on android
<Stack.Screen
options={{headerBackVisible: false}}
/>
example use of in Stack
const CustomerStack = () => {
return (
<Stack.Navigator>
<Stack.Screen
name="First"
component={First}
options={{headerShown: false}}
/>
<Stack.Screen
name="Third"
component={Third}
options={{headerTitle: '', headerTransparent: true}}
/>
</Stack.Navigator>
);
}
If you don't want the default header then use like this
screenOptions={{ headerShown: false }}
and write custom code for the header with back button in your component
(If your are using class component) Then
<TouchableOpacity onPress={()=>this.props.navigation.goBack()} style={{width:'100%', height:45, flexDirection:'row'}}> <Image source={require('back button image path')}/> </TouchableOpacity>
if you want header title too then,
<TouchableOpacity onPress={()=>this.props.navigation.goBack()} style={{width:'100%', height:45, flexDirection:'row'}}> <Image source={require('back button image path')}/> <Text>SearchListScren</Text> </TouchableOpacity>
Put this code at top of the component code under a container

Stack.Navigator fade-transition between Stack.Screens in React-native?

How can I add a transition effect to Stacked Screes in React-native?
<NavigationContainer>
<Stack.Navigator
screenOptions={{
headerShown: false,
}}
>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Stocks" component={StocksScreen} />
</Stack.Navigator>
</NavigationContainer>
Is there a default way to achieve a fadeIn / fadeOut effect?
The simplest way to achieve fade effect:
const forFade = ({ current }) => ({
cardStyle: {
opacity: current.progress,
},
});
If you want to apply fade effect for the entire navigator:
<Stack.Navigator
screenOptions={{
headerShown: false,
cardStyleInterpolator: forFade,
}}>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Stocks" component={StocksScreen} />
</Stack.Navigator>
Also you can apply cardStyleInterpolator for single screen via setting options:
<Stack.Screen
name="Home"
component={HomeScreen}
options={{ cardStyleInterpolator: forFade }}/>
You can customize forFade function in order to achieve other effects, or also you can use some pre-made interpolators, as:
forHorizontalIOS
forVerticalIOS
forModalPresentationIOS
forFadeFromBottomAndroid
forRevealFromBottomAndroid
import { CardStyleInterpolators } from '#react-navigation/stack';
<Stack.Screen
name="Profile"
component={Profile}
options={{
cardStyleInterpolator: CardStyleInterpolators.forFadeFromBottomAndroid,
}}
/>;
More info here: https://reactnavigation.org/docs/stack-navigator/#animations
For React Navigation 6.xx you can use the animation option:
<Stack.Screen
name="Profile"
component={Profile}
options={{ animation: 'fade' }}
/>
Supported values:
"default": use the platform default animation
"fade": fade screen in or out
"flip": flip the screen, requires presentation: "modal" (iOS only)
"simple_push": use the platform default animation, but without shadow and native header transition (iOS only)
"slide_from_bottom": slide in the new screen from bottom
"slide_from_right": slide in the new screen from right (Android only, uses default animation on iOS)
"slide_from_left": slide in the new screen from left (Android only, uses default animation on iOS)
"none": don't animate the screen

React navigation 5.x / React native – bottom-tabs navigation with same instance of component

I want to reuse the same instance of one component in two tabs (bottom bar tabs).
created with const Tab = createBottomTabNavigator();
Tab stack:
<Tab.Navigator
tabBarOptions={{
activeTintColor: Colors.tabs.active,
inactiveTintColor: Colors.tabs.inactive,
}}>
<Tab.Screen
name="NavigationMap"
component={Map}
options={{
tabBarLabel: 'Navigation',
}}
/>
<Tab.Screen
name="DiscoveryMap"
component={Map}
options={{
tabBarLabel: 'Discover',
}}
/>
<Tab.Screen
name="Other"
component={OtherComponent}
options={{
tabBarLabel: 'Other',
}}
/>
</Tab.Navigator>
I want to have the same behavior than in the Google Maps application on Android with the "Explore" and "Commute" tabs: stay in the same screen with a different state. I do not want to reload completely my map between the 2 tabs (and have independant zoom levels, center, ...).
Note: I cannot achieve that behavior with the tabPress method.
You can add focus listeners to both screens. Here, you can set the context or global state that can be accessed by the HomeNavigation component and change the behaviour.
<Tab.Screen
name="Home"
component={HomeNavigation}
listeners={{
focus: () => console.warn('focused 1'),
}}
/>
<Tab.Screen
name="Home2"
initialParams={{testing: true}}
component={HomeNavigation}
listeners={{
focus: () => console.warn('focused 2'),
}}
/>