Transition in the application with navigation hooks - react-native

I have an application that uses Hooks
My navigation:
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name='Home' component={Home} options={{ headerShown: false }} />
<Stack.Screen name='Learning' component={Learning}
options={({ route }) => ({
headerTransparent: true,
title: route.params.screen
})} />
</Stack.Navigator>
</NavigationContainer>
The standard transition is the outgoing screen from the bottom of the screen
I would like to make the screen disappear and a second one appear (fadeIn, fadeOut)
In class-based applications, I can use this library to change the style of transition between screens:
(it doesn't work on hooks)
react-navigation-transitions

Related

Bottom tab bar: Unmountonblur:true gives flickering effect on screens when switching between tabs in react native. How to handle this?

I am using bottomtab navigator to navigate between screens.
At the same time, I need to rerender my screens when switch from one tab to other which refresh the from api call.
Unmountonblur:true option in <Tab.Navigator> works as expected. But white flickering effect is very annoying. Any alternative to rerender the page each time ?
Below is my code:
export default function App() {
<NativeBaseProvider theme={paTheme}>
<NavigationContainer theme={{ colors: { background: 'primary.500' } }}>
<Stack.Navigator
screenOptions={{
headerShown: false,
}}
>
<Stack.Screen name="SplashScreen" component={SplashScreen} />
<Stack.Screen name="SignIn" component={SignIn} />
<Stack.Screen name="SignUp" component={SignUp} />
<Stack.Screen name="MainNavigator" component={MainNavigator} />
</Stack.Navigator>
</NavigationContainer>
</NativeBaseProvider>
}
function MainNavigator() {
<Tab.Navigator
initialRouteName="Screen1"
tabBarOptions={{
keyboardHidesTabBar: true,
}}
unmountOnBlur: true,
>
<Tab.Screen
name="Screen1"
options={{
title: "Home",
}}
component={Home} />
<Tab.Screen
name="Screen2"
options={{
title: "Account",
}}
component={Screen2} />
</Tab.Navigator>
}

React navigation initialRouteName property not working as expected

In my react native app I nested stack navigation inside the tab navigation.
I can't access the screen that I set as an initial route in stack navigation.
The tab navigation component is
<Tab.Navigator initialRouteName='HomeNav' >
<Tab.Screen name="HomeNav" component={HomeNav}
options={{
tabBarIcon: ({ color, size }) => (
<FIcon name="home" color={color} size={size} />
),
}}
/>
<Tab.Screen name="Search" component={Search}
options={{
tabBarIcon: ({ color, size }) => (
<FIcon name="search" color={color} size={size} />
)
}}
/>
<Tab.Screen name="Cart" component={Cart}
options={{
tabBarIcon: ({ color, size }) => (
<MCIcon2 name="cart" color={color} size={size} />
)
}}
/>
<Tab.Screen name="AccountNav" component={AccountNav}
options={{
tabBarIcon: ({ color, size }) => (
<MCIcon2 name="account" color={color} size={size} />
)
}}
/>
</Tab.Navigator >
And here is the account navigation component
const AccountNav = () => {
return (
<Stack.Navigator
initialRouteName="Account"
screenOptions={{
headerShown: false
}}
>
<Stack.Screen name="Account" component={Account} />
<Stack.Screen name="MyOrders" component={MyOrders} />
<Stack.Screen name="Profile" component={Profile} />
</Stack.Navigator>
);
when I try to navigate to MyOrders screen from the other screens. it gets stuck and cannot access the initial route screen (Account).
I had this issue aswell, I solved it by adding lazy: false to the tab navigators screenOptions prop.
screenOptions={{
headerShown: false,
lazy: false
}}
Documentation says that "Routes are lazily initialized -- their screen components are not mounted until they are first focused.", my guess is that the initial route you specify won't "register" until the screen's components are properly mounted (until the screen is focused), so when you go to your AccountNav, the initial route becomes the one you navigated too, bypassing the prop.
The issue with this is that you're mounting all the screen components from all the screens and that may impact performance depending on your application I guess

How to enable Drawer Navigation only on specific screen (e.g. Home Screen) [react native] [react navigation]

Use case of this problem is to have Drawer menu like "Settings" available only form "Home Screen". And at "Home screen" could be many buttons that link to other screens of Stack Navigation where Drawer is not available.
Main question is how to enable Drawer Navigation only on specific screen of Stack Navigator?
On below example Drawer is available on all pages of Stack. I tried with gestureEnabled but it didn't work:
const StackHome = () => (
<Stack.Navigator>
<Stack.Screen name="Home" component={Home} />
<Stack.Screen name="Example1" component={Example1} />
<Stack.Screen name="Example2" component={Example2} />
</Stack.Navigator>
);
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={StackHome} />
<Drawer.Screen name="Settings" component={Settings} />
</Drawer.Navigator>
On the other hand if I try make Drawer as one of Stack screen, then I have always the same Header bar (example "Header")
Put your drawer navigator inside the home screen:
const DrawerHome = () => (
<Drawer.Navigator screenOptions={{ headerShown: true }}>
<Drawer.Screen name="Home" component={Home} />
<Drawer.Screen name="Settings" component={Settings} />
</Drawer.Navigator>
);
const StackHome = () => (
<Stack.Navigator>
<Stack.Screen
name="DrawerHome"
component={DrawerHome}
options={{ headerShown: false }}
/>
<Stack.Screen name="Example1" component={Example1} />
<Stack.Screen name="Example2" component={Example2} />
</Stack.Navigator>
);

Tab navigator adding header

I am using React navigation. I want to add headers to my tab navigator components. How can I do that?
Tab navigation function
const TabNavigation = () => {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={Welcome} />
<Tab.Screen name="Favorites" component={Favorites} />
<Tab.Screen name="Profile" component={Profile} />
</Tab.Navigator>
);
};
Stack navigator function
<Stack.Navigator
initialRouteName="SignIn">
<Stack.Screen name="SignIn" component={SignIn} />
<Stack.Screen name="TabNavigation" component={TabNavigation}/>
<Stack.Navigator>
You can customize your header dynamically in Stack Navigation screen options prop. For example you can create custom functions like getTitle to determine title dynamically depending on your route.
<Stack.Screen
name="TabNavigation"
component={TabNavigation}
options={({ route }) => ({
//title: getTitle(route),
//headerStyle: styles.headerStyle
//headerTitleStyle: styles.headerTitleStyle
})}
/>

Dynamic Title change on the screen

I have a navigation code:
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name='Home' component={Home} options={{ headerShown: false }} />
<Stack.Screen name='Learning' component={Learning}
options={{
headerTransparent: true,
title: 'Learning',
headerTitleAlign: 'center',
}} />
</Stack.Navigator>
</NavigationContainer>
I use the Learning screen for two functional application screens:
A
B
On screen A, I have two buttons:
<TouchableOpacity onPress={() => navigation.navigate('Learning', { screen: 'Learning' })}/>
<TouchableOpacity onPress={() => navigation.navigate('Learning', { screen: 'Repeats' })}/>
Depending on this content, {screen: 'Learning'} is loading some other data
This screen has a title header
How do you make it load a different title depending on the button you click?
I can't find a solution how to do it for Components built on functions and Hooks
The options prop can take a function and provide {route, navigation} object as an argument for you, so to use the params in the header, you can do this:
<Stack.Screen
name="Learning"
component={Learning}
options={({ route }) => ({ title: route.params.screen })}
/>
I'm not sure what difference the functional components and hooks make in this case, but in case I misunderstood the question, you can use useNavigation and useRoute hooks in your functional components and do the same things that you do in classes.