Hide parent's navigation header from the nested navigator - react-native

I'm developing my first react native app. I've an issue with the nested navigations in the app.
I've the following navigations:
Main App Navigator : createStackNavigator
Authentication Navigator : createStackNavigator
Bottom Bar Navigator : createBottomTabNavigator
Top Tab Navigator : createMaterialTopTabNavigator
My too nested Navigator : createStackNavigator
What i want ?
I'm trying to hide the BottomBar & TopTab Navigators headers form a screen in the last nested navigator.
What I did?
Ive tried to set the header as null in my nested nav, but thats hides the nested header not the parents headers.
I also tried to set the parents headers as nulls, but thats hide them from all screen.
I need to only hide them in this nested screen. Can I change the parents headers property from my nested React Class?

Unfortunately, I didn't figure how to do that without using redux.
So I had to do a workaround.
I declared my Nested Navigator directly in the Main Navigator. "in the same level as Authentication & Bottom Bar Navigations" and set the header as null for this specific nav.
And then, navigate to that nested whenever i want.
Also, I had to add my custom icon to navigate the user back. because in our case there is no history in the new navigator in order to navigate back to.
so, i did like this:
static navigationOptions = ({ navigation }) => ({
headerLeft: (
<Icon
name="chevron-left"
color="#fff"
underlayColor="#4BA6F8"
onPress={() => {
const backAction = NavigationActions.back();
navigation.dispatch(backAction);
}}
/>
),
});
I know this is not the real answer for my question, but at least it solved my issue.

Related

Make all tab bar buttons unfocused on specific screens

I have a react native app which uses react navigation (V6.x for sure). My app has a main navigator which is a bottom-tabs navigator and contains three screens (tabs). Every one of these screens are stack navigators themselves. Let's say one of my tabs is named Wallet (others are Settings and Transactions). Inside this Wallet screen (which is a stack navigator), i have a HomePage screen, a Receive screen and a Send screen. I want to achieve the following behavior (like below screenshot from designs):
Whenever the user goes to one of Send or Receive screens, i want all the tab bar buttons become unfocused (tab bar is still visibe though). And whenever the user gets back to HomePage screen (or going to Settings or Transactions tab by pressing the corresponding tab button), I want the relevant tab button to get focused again. How can i achieve that with react navigation itself?
(My project is managed by redux, but i prefer not to use state management tools and use react navigation itself)
You can do that, but checking child navigation state inside your TabNavigator's screenOptions.
screenOptions={({ route, navigation }) => {
// get wallet stack route
const walletStack = navigation.getState().routes.find((route) => route.name === 'Wallet');
// get current wallet stack focused screen
const walletRouteName = getFocusedRouteNameFromRoute(walletStack);
const shouldBeUnfocused =
walletRouteName === 'Send' || walletRouteName === 'Receive';
{...}
}
Based on shouldBeUnfocused you can render proper icons and colors. Here is the snack with example code. You can red here about customizing tab bar's appearance.

react navigation - navigate to a specific tab within a screen of two tabs

I'm new to react native navigation. I have two different tabs, one is called "Current" and one "History" and a DisplayScreen component which is responsible to show both tabs. The stack of this component in the navigation file is set like so:
function DisplayStack () { return (
<Service.Navigator {...(css.DisplayStack || {})}>
{screen(Service.Screen, 'DisplayScreen ', scr.DisplayScreen)}
</Service.Navigator>)}
Then I have a tab stack with this DisplayStack:
function TabStack () { return (
<Tab.Navigator {...TabStackParams}>
{screen(Root.Screen, 'HomeStack', HomeStack)}
{screen(Root.Screen, 'DisplayStack ', DisplayStack )}
</Tab.Navigator>)}
Navigating to the DisplayStack is easy:
this.navigate('TabStack', { screen: 'DisplayStack ' })
But with the current functionality, navigating to it opens the component which is reponsible for displaying the two tabs. But how can I navigate to a specific tab inside this component? Should I change the way my navigation is constructed? Or send props to the DisplayScreen (which loads the two tabs) to tell it to open the desired screen out of the two?

How to goBack globally between stacks in React Navigation?

I am using react navigation ("#react-navigation/native": "^5.1.3") and I have the following setup:
BottomNavigation
-stack1
-stack2
It looks like goBack() is local to the stack. What that means is that if I navigate from a page in stack1 to a page in stack2, I am unable to go the the page I came up from.
Solutions (or rather hacks) that didn't work for me:
pass the source screen as param and then navigate. That isn't a real back button and does not play well with android back button.
Put all pages in bottom navigation. Bottom navigation does not have animations it seems, so I can not achieve the right transitions
Put all pages in stack navigation. In this case I lose the fixed bottom navigation. I can add it to each page, but when transitioning it will go away with the old screen and come again with the new one, which is undesirable.
So I am wondering if I am missing something big here, like a globalBack() that I overlooked?!
And also, I am looking for a solution to this problem which remains.
Naturally if you have bottoms tabs with each tab having its own stack navigator, calling navigation.goBack() will go back from one screen inside stack navigator to previous screen inside that same stack navigator. That's how navigation works in pretty much every app. Pressing back button or swiping back does not change tab for you, tabs are more like separate small apps by itself. If you want to specifically jump from one tab to another instead of going back in stack, use navigation.dispatch(TabActions.jumpTo('Profile')). If pressing something inside tab#1 makes you go to to tab#2 then this screen most likely also belongs to tab#1
also, take a look at backBehavior prop of Tab.Navigator, it might be doing what you want depending on what exactly it is you want https://reactnavigation.org/docs/bottom-tab-navigator/#backbehavior
I'm using bottom tab navigator with 2 stacks as well. I faced similar issue and agree with #Max explanation. Due to my Notification screen is in Stack 1, I have to goBack to Notification after navigating away to Detail screen. After searching for the fix, I'm using this workaround (for v6).
Tab 1 - Stack 1 (Home > Notification screen)
Tab 2 - Stack 2 (Reward Home > Reward Detail screen)
I passed a param when navigating from Notification to RewardDetail. Then I override the headerLeft and use BackHandler to handle Android back function.
Notification.js
navigation.navigate('RewardStack', {
screen: 'RewardDetail',
initial: false,
params:{notification: notification_data_source}
})
RewardDetail.js
const payload = route.params.notification
//1. override headerLeft button
useLayoutEffect(() => {
if(payload)
navigation.setOptions({
headerLeft: () => (
<Button
TouchableComponent={TouchableOpacity}
buttonStyle={{paddingTop:4, paddingLeft:0}}
type='clear'
icon={<Icon name={'chevron-left'} size={30} style={{color:'#FFF'}} />}
onPress={()=>{
navigation.goBack()
navigation.navigate('Notification') //can use this only
}}
/>
)
})
}, [navigation]);
//2. Add BackHandler
useEffect(() => {
const onBackPress = () => {
if (payload) {
navigation.goBack()
navigation.navigate('Notification') //can use this only
return true
} else {
return false
}
}
BackHandler.addEventListener('hardwareBackPress', onBackPress)
return () => BackHandler.removeEventListener('hardwareBackPress', onBackPress)
}, [navigation]);
I can just use navigation.navigate('Notification') to return to Notification but this will cause Detail screen to stay mounted in Stack 2. I want the Stack 2 to return to RewardHome after go back to Notification. Hence I used:
navigation.goBack() //pop screen to RewardHome
navigation.navigate('Notification') //jump to Notification

BottomNavigation in react native

I create a bottom navigation in my react native project. But its not looking good in Iphone10.
It showing extra space in bottom.Please help me how to resolve this.
This is below code i tried.
import BottomNavigation,{FullTab} from 'react-native-material-bottom-navigation'
<BottomNavigation
onTabPress={newTab => this.clickoftab(newTab.key)}
renderTab={this.renderTab}
tabs={this.tabs}
/>
My render tab part is this
renderTab = ({ tab, isActive }) => {
return (
<FullTab
style={{padding:0,margin:0}}
key={tab.key}
isActive={isActive}
label={tab.label}
renderIcon={this.renderIcon(tab.icon)}
/>
)
}
This is my output which i want to change in bottom navigation
Depending of your architecture app, if like you say in the comments, if you use SafeAreaView I thought in create the BottomNavigation at the same level of the SafeAreaView. I mean (sorry my english), I suppose that you have the SafeAreaView in your "Father file" like App.js. So, at the same time you can manage the BottomNavigation from there. So, you could put SafeAreaView inside of BottomNavigation making BottomNavigation the father of your app I guess. I don't know if I am explaining well. The conclusion could be that
just apply SafeArea To things that are inside of Navigation instead of
full application.

Using Navigator in React Native

I am using the Navigator component for React Native and so far so good, but ...
I can't seem to push() to the navigator from within the same component. Here is an example:
updateNav(){
navigator.push({page: 'newPage'});
}
render(){
return (
<Navigator initialRoute={{page: INITIAL_TAB}} />
)
}
When I call
updateNav()
I get an error saying that 'navigator' is undefined.
Also, I can pass the navigator to children and update the Navigator from the children via 'props' with no problem. But I have a case where I need to update the push to the Navigator from within the same component that has the Navigator component.
The navigator is a property that you pass down to your scenes, so it won't be available in the same component you're rendering Navigator. I ran into this issue too and just moved up the Navigator to a higher component and made the current one the initial route.
I think navigator should be on your props
this.props.navigator