React native using tab navigator and drawer navigator - reactjs

I'm totally new to React-native and am currently trying to set up the navigation for my application.
I have a stack navigation that is leading me from the login to the tab navigator. The tab navigator has 4 tabs (HomeRoutes, ProductCatalogueRoutes, MyCustomerRoutes and DrawerRoutes). The last one should open a drawer navigator when clicked on. However, when I click on the 4th tab, the first screen of the drawer navigation appears put I am not able to open the drawer navigation.
I feel like I missed something basic but even after reading through several other questions, I don't get it. Let me know if you need any further information.
Note: Alternatively, it would also be fine for me to have the drawer navigation on the left header position of the tab navigator.
Note 2: I have also changed DrawerNavigation to createDrawerNavigation, etc.
Thanks for your help!
import React, { Component } from 'react';
import {StyleSheet, Text, View} from 'react-native';
import {DrawerNavigator, StackNavigator, TabNavigator} from 'react-navigation'
import Icon from 'react-native-vector-icons/FontAwesome';
import MyCustomers from "./mycustomers";
import ProductCatalogue from "./productcatalogue";
import Login from "./login";
import Home from "./home";
import Plain from "./plain";
const ProductCatalogueRoutes = StackNavigator({
ProductCatalogue: { screen: ProductCatalogue },
})
const MyCustomerRoutes = StackNavigator({
MyCustomers: { screen: MyCustomers },
})
const DrawerRoutes = DrawerNavigator({
Plain: { screen: Plain},
MyCustomers: {screen: MyCustomerRoutes},
ProductCatalogue: {screen:ProductCatalogueRoutes},
})
const HomeRoutes = StackNavigator({
Home: { screen: Home },
// DrawerRoutes: { screen: DrawerRoutes}, //if the drawer menu is part of the header
})
const Tabs = TabNavigator({
Home: { screen: HomeRoutes },
MyCustomers: {screen: MyCustomerRoutes},
ProductCatalogue: {screen: ProductCatalogueRoutes},
Menu: {screen: DrawerRoutes}
},
{order: [ 'Home', 'ProductCatalogue', 'MyCustomers' , 'Menu'],
animationEnabled:true,
}
);
export const Stack = StackNavigator({
Login: {screen: Login},
TabNavigation: {screen: Tabs}
},
{initialRouteName: 'Login',
header: null,
navigationOptions: {
headerVisible: false,
header: null,
},
});
const styles = StyleSheet.create({
title: {
color: '#ff5d00',
fontSize: 15,
textAlign: 'center',
marginTop: 2,
opacity: 0.9,
}
});

Related

React Native | Navigator talking back to Initial Page

I have this navigator Setup on my Routes Page and I am expecting that when I press this.props.navigation.goback function it should take me to the second page if I am on the third page but apparently it is taking me to the first page.
Even with the natural goback Behavior of Android or IOS, it's taking me to the First Page.
I navigate Via
this.props.navigation.navigate('Screens')
NavigatorPage: Here I am using DrawerNavigator
import { createAppContainer ,createDrawerNavigator} from 'react-navigation';
import Dashboard from './pages/dashboard';
import Splash from './pages/Splash';
import Readmore from './pages/readmore';
import Tabs from './pages/tab';
import Check from './pages/checking';
import Search from './pages/searchpage';
import SideMenu from './componenet/sideMenu'
const AppNavigator = createDrawerNavigator({
// Prac: { screen: Check},
Splash :{ screen: Splash},
Dashboard: { screen: Dashboard},
Readmore: { screen: Readmore },
Tabs: { screen: Tabs },
Search: { screen: Search }
},
{
contentComponent: SideMenu,
drawerWidth: 300,
headerMode: 'none',
navigationOptions: {
headerVisible: false,
}
});
export default createAppContainer(AppNavigator);
Edit ONE After doing this
const AppNavigator = createDrawerNavigator({
// Prac: { screen: Check},
stacknav:{screen:stacknav}
},
{
contentComponent: SideMenu,
drawerWidth: 300,
headerMode: 'none',
navigationOptions: {
headerVisible: false,
}
});
const stacknav = createStackNavigator ({ Splash :{ screen: Splash},
Dashboard: { screen: Dashboard},
Readmore: { screen: Readmore },
Tabs: { screen: Tabs },
Search: { screen: Search } });
export default createAppContainer(AppNavigator);
Getting an Error of this
The answer is simple
Put all the screens of your drawernavigator inside a new createstacknavigator.
Then inherit stack navigator inside drawernavigator as a child.
I.e
const stacknav = createStackNavigator ({ Splash :{ screen: Splash},
Dashboard: { screen: Dashboard},
Readmore: { screen: Readmore },
Tabs: { screen: Tabs },
Search: { screen: Search } });
Const appNavigator = createdrawernavigator({ stacknav:{screen:stacknav}},{ ...}}
Hope it helps. Sorry for poor code structure as i am replying from a mobile device. But surely it ll be of your help. Thanks !
Use createStackNavigator instead of createDrawerNavigator.
I have found the solution and before that, there are some things that we need to watch.
Make sure every const Name start with Capital Letter
I couldn't just simply import the stack navigator to the drawer navigator from the same file.
So I put the stack into another file and export default it directly into my Drawernavigator.
And that fixed my issue

React Navigation V2 Hide Single Tab From Bottom Tab Navigator

I am working on a React Native app. When the user loads the app, I want the first screen they see to be a Home screen to tell them about some of the features of the app. Currently, I am using a BottomTabNavigator with nested StackNavigators inside. I have been able to get my Home screen added, but it always shows up the in TabNavigator. Is there a way to make a single tab item not present in any of the screens?
PS. I have tried using a StackNavigator as my parent like the following, but my TabNavigator does not show up:
const AppNavigator = createBottomTabNavigator({
Item1: Item1,
Item2: Item2,
Item3: Item3,
Item4: Item4,
Item5: Item5
});
const MainNavigator = createStackNavigator({
Home: Home,
Content: AppNavigator
}
Any ideas?
UPDATE
If I have screens called Item1, Item2, Item3, Item4, Item5, and Home, I want to make it display Home first. In addition, I want the TabBar visible at the bottom, but it can't include the Home screen.
You likely want to nest your main app tab navigator inside another tab navigator like this:
const AppNavigator = TabNavigator({
Main: { screen: MainScreen },
Settings: { screen: SettingsScreen },
});
export default TabNavigator(
{
Home: { screen: HomeScreen },
App: { screen: AppNavigator },
},
{
navigationOptions: ({ navigation }) => ({
tabBarVisible: false,
}),
}
);
I think SwitchNavigator is what do you need https://reactnavigation.org/docs/en/switch-navigator.html. Try like this
const MainNavigator = createSwitchNavigator({
Home: Home,
Content: AppNavigator
}
If you want TabNavigator you can simply do the same
const MainNavigator = createBottomTabNavigator({
Home: Home,
Content: AppNavigator
}
Create a custom tabBarComponent for your Tab Navigator to use.
Map through the routes in that custom tabBarComponent and don't render anything for that Tab if route.routeName === 'Home'.
const TabBar = props => {
return (
{navigation.state.routes.map((route, i) => {
if (route.routeName !== 'Home') {
return (
<Tab...

React Navigation confusion

I started learning React Native, I know how to create TabNavigator or DrawerNavigator but I need access to props.navigation on landing page where I don't have TabNavigation, how I'am supposed to get it.
I tried this:
const App = createStackNavigator({
LandingScreen: { screen: LandingScreen },
Register: { screen: RegisterScreen },
Login: { screen: LoginScreen}});
But still, this.props are empty object.
And what is stackNavigator in plain language, does it just define navigation in order to be able to use navigation ?
In your LandingScreen you can able to get the this.props.navigation. You can show your TabNavigation as your initial route. You can even set Stack Navigation for each Tab. For React Navigation(v2) Documentation https://reactnavigation.org/docs/en/tab-based-navigation.html
Stack Navigation:
Provides a way for your app to transition between screens where each new screen is placed on top of a stack.
//Stack Navigator
const App = createStackNavigator({
Home: { screen: Tabs }, //You can nest your TabNavigator here, Hence the LandingScreen inside your HomeStack will shown as your Initial screen
Register: { screen: RegisterScreen },
Login: { screen: LoginScreen}});
//Sample Tab Navigator
const Tabs = createBottomTabNavigator(
{
Home: HomeStack,
Settings: SettingsStack,
},
{
/* Other configuration remains unchanged */
}
);
const HomeStack = createStackNavigator({
LandingScreen: LandingScreen,
Details: DetailsScreen,
});
const SettingsStack = createStackNavigator({
Settings: SettingsScreen,
Details: DetailsScreen,
});
You can get your navigation Prop by using below
//LandingScreen Component
export default LandingScreen extends Component{
static navigationOptions = ({navigation}) => ({ //you can able to destructure your navigation prop here
headerTitle: 'Langing Page'
})
render(){
return(
//your logic here
)
}
}

Displaying headers with DrawerNavigator in React Native

I'm looking to use DrawerNavigator along with StackNavigator so I can display a header for my screens, everything is working fine but I messed up with the router logic, my issue is that the drawer do not render items but only the first one.
const Router = StackNavigator({
Home: {screen: Screen1},
Other: {screen: Screen2}
}, {
navigationOptions: {
headerStyle: {backgroundColor: '#333333'},
headerTintColor: '#fff'
}
});
const Drawer = DrawerNavigator({
App: {screen: Router},
});
export default Drawer;
Can someone please explain why I'm only seeing the first item in drawer? When trying to fix that I added a second item to drawer config router like that
const Drawer = DrawerNavigator({
App: {screen: Router},
App: {screen: Router},
});
It add a second item to the drawer but with the wrong title, it use title for screen one but the link is correct, it redirect to the second screen. so how can I fix those labels?
Better way of doing this is by creating drawernavigator with custom "contentComponent". This way you will have more control of what titles you want to display in the drawer, on click of title which screen it has to navigate to, background color of the drawernavigator.
So the DrawerNavigator is instantiated like this (from the docs):
const MyApp = DrawerNavigator({
Home: {
screen: MyHomeScreen,
},
Notifications: {
screen: MyNotificationsScreen,
},
});
Therefore by doing what you did the first time:
const Drawer = DrawerNavigator({
App: {screen: Router},
});
, you're telling DrawerNavigator that there is only one element to be added to the drawer menu, regardless of what that screen "Router" contains, for DrawerNavigator it is just one element.
So in order to correctly add your screens to the drawer:
const HomeRoute = StackNavigator({
Home: {screen: Screen1},
}, {
navigationOptions: { ... }
});
const OtherRoute = StackNavigator({
Other: {screen: Screen2},
}, {
navigationOptions: { ... }
});
const Drawer = DrawerNavigator({
Home: { screen: HomeRoute },
Other: { screen: OtherRoute }
});
export default Drawer;

Integrate StackNavigator with TabNavigator

How do I combine StackNavigator and TabNavigator?
My following code works:
index.android.js :
import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';
import { StackNavigator,TabNavigator } from 'react-navigation';
import TestComp1 from './src/components/TestComp1'
import TestComp2 from './src/components/TestComp2'
import TestComp3 from './src/components/TestComp3'
import TestComp4 from './src/components/TestComp4'
import TestComp5 from './src/components/TestComp5'
export default class myApp extends Component {
render() {
return (
<MyApp />
);
}
}
const MyApp = StackNavigator({
TestComp1: {screen:TestComp1},
TestComp2: {screen:TestComp2}
});
const Tabs = TabNavigator({
TestComp3: {screen:TestComp3},
TestComp4: {screen:TestComp4}
TestComp5: {screen:TestComp5}
});
AppRegistry.registerComponent('myApp', () => myApp);
This works only for StackNavigator. I want to keep the existing navigation and integrate TabNavigation. Now in TestComp1 if I do the following:
TestComp1 :
import { StackNavigator, TabNavigator } from 'react-navigation';
import { FooterTabs } from './routes/FooterTabs';
export default class HomePage extends Component {
static navigationOptions = {
header: null
};
render() {
return(
<View style={styles.container}>
<View style={styles.mainContent}>
<Button
onPress={() => this.props.navigation.navigate('TestComp1', {name: 'Lucy'})}
title="NewPage"
/>
<FooterTabs /> //Page shows all StackNavigator screens if I add this
</View>
</View>
)
}
}
And the FooterTabs:
import { StackNavigator, TabNavigator } from 'react-navigation';
import TestComp3 from '../TestComp3';
import TestComp4 from '../TestComp4';
import TestComp5 from '../TestComp5';
export const FooterTabs = TabNavigator({
Tab1: {
screen: TestComp3
},
Tab2: {
screen: TestComp4
},
Tab3: {
screen: TestComp5
},
})
The FooterTabs is shown but TestComp1 and TestComp2 are also shown everything below one another. How do I fix this? Thanks.
UPDATE 1:
UPDATE 2:
const Tabs = TabNavigator({
TestComp3: {screen:TestComp1},
TestComp4: {
screen:TestComp4,
navigationOptions: ({ navigation }) => ({
title: "TestComp4",
tabBarIcon: ({ tintColor }) => <MaterialIcons name="accessibility" size={20}/>
})
}
UPDATE 3
I added another const for DrawerNavigator and configured it like this:
const Drawer = DrawerNavigator({
First:{
screen: DrawerScreen1
},
Second:{
screen: DrawerScreen2
}
},{
initialRouteName:'First',
drawerPosition: 'left'
});
And included in the app:
const MyApp = StackNavigator({
TestComp1: {screen:TestComp1},
TestComp2: {screen:TestComp2},
Tabs: {
screen: Tabs
},
Drawer: {
screen: Drawer
},
}, {
initialRouteName: "Tabs"
});
I'm calling it :
<Button
onPress={() => this.props.navigation.navigate('DrawerOpen')}
title="Show Drawer"
/>
OnPress of this button the DrawerScreen1 is called but as a component, it does not show as a drawer from the left. What am I missing?
You can try this:
const Tabs = TabNavigator({
TestComp3: {screen:TestComp3},
TestComp4: {screen:TestComp4}
TestComp5: {screen:TestComp5}
});
const MyApp = StackNavigator({
TestComp1: {screen:TestComp1},
TestComp2: {screen:TestComp2},
Tabs: {
screen: Tabs
}
}, {
initialRouteName: "Tabs"
});
and remove <FooterTabs /> from TestComp1
Let's see now. What you need is first a StackNavigator then inside one of the screens of the StackNavigator you need a TabNavigator. Right?
The answer to this would be the following:
For your index.android.js:
import React, { Component } from 'react';
import { AppRegistry, Text, View } from 'react-native';
import { StackNavigator } from 'react-navigation';
import TestComp1 from './src/components/TestComp1'
import TestComp2 from './src/components/TestComp2'
// Don't need to export default here since this is the root component
// that is registered with AppRegistry and we don't need to import it anywhere.
class myApp extends Component {
render() {
return (
<MyApp />
);
}
}
// Notice that these two screens will consist the navigation stack.
// Assume, TestComp1 contains our Tabbed layout.
const MyApp = StackNavigator({
TestComp1: { screen:TestComp1 }, // This screen will have tabs.
TestComp2: { screen:TestComp2 }
});
AppRegistry.registerComponent('myApp', () => myApp);
Let's now move on to your TestComp1, which is the screen that has your tabs.
TestComp1:
// ... all imports here.
// This should be your first tab.
class Home extends Component {
static navigationOptions = {
// Label for your tab. Can also place a tab icon here.
tabBarLabel: 'Home',
};
render() {
return(
<View style={styles.container}>
<View style={styles.mainContent}>
// This will change your tab to 'Profile'.
<Button
onPress={() => this.props.navigation.navigate('Profile', {name: 'Lucy'})}
title="NewPage"
/>
</View>
</View>
)
}
}
// This can be your second tab and so on.
class Profile extends Component {
static navigationOptions = {
// Label for your tab.
tabBarLabel: 'Profile',
};
render() {
return (
<Text>This is the profile Tab.<Text>
);
}
}
export default TabNavigator({
Home: {
screen: Home,
},
Profile: {
screen: Profile,
},
}, {
// This will get the tabs to show their labels/icons at the bottom.
tabBarPosition: 'bottom',
animationEnabled: true,
tabBarOptions: {
activeTintColor: '#e91e63',
},
});
So essentially, your TestComp1 has two components (Home and Profile) inside it which are both parts of TabNavigator so they'll act as tabs. (You don't need to worry about a separate footer component as ReactNavigation places that automatically using your component's navigationOptions) We'll be exporting this TabNavigator instance that we'll use as an import to index.android.js and we'll place this import inside our StackNavigator as a screen of the app.
This way you've incorporated Tabs as well as StackNavigator inside your RN app. Also, tabBarPosition: 'bottom' places your tabs at the bottom.
You also no longer to maintain a separate FooterTabs component as you can see.
Read up the docs if you need more clarity or fine-tuning.
Hope I've helped. :)

Resources