I am implementing react-navigation-drawer from React Navigation Library. But facing problem related to header. The header bar is not showing in any of the screens.
This is my App.js
import React from "react";
import { StyleSheet, ScrollView, View } from "react-native";
//import DrawerNavigator from "./navigation/DrawerNavigator";
import { Platform, Dimensions } from "react-native";
import { createAppContainer } from "react-navigation";
import { createDrawerNavigator } from "react-navigation-drawer";
import Home from "./components/home";
import Contact from "./components/contact";
const WIDTH = Dimensions.get("window").width;
const RouteConfigs = {
Home: {
screen: Home
},
Contact: {
screen: Contact
}
};
const DrawerNavigatorConfig = {
drawerWidth: WIDTH * 0.75,
drawerType: "both",
initialRouteName: "Home"
};
const DrawerNavigator = createDrawerNavigator(
RouteConfigs,
DrawerNavigatorConfig
);
const MyApp = createAppContainer(DrawerNavigator);
export default class App extends React.Component {
render() {
return <MyApp />;
}
}
And this is my home screen
import React, { Component } from "react";
import { View, Image, Text, StyleSheet, ScrollView } from "react-native";
import { FontAwesomeIcon } from "#fortawesome/react-native-fontawesome";
import { faTruck, faHome } from "#fortawesome/free-solid-svg-icons";
class Home extends Component {
static navigationOptions = {
headerTitle: "Home",
drawerIcon: ({ tintColor }) => <FontAwesomeIcon size={25} icon={faHome} />
};
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Home Screen</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#F5F5F5",
flexDirection: "column"
},
icon: {
width: 24,
height: 24
}
});
export default Home;
Can anyone help me. Thanks in advance!!!
#hongdeveloper this is a simple example solution for react navigation 5:
function Root() {
return (
<Stack.Navigator>
<Stack.Screen options={{title: "Profile"}} name="Profile" component={Profile} />
<Stack.Screen options={{title: "Settings"}} name="Settings" component={Settings} />
</Stack.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} />
<Drawer.Screen name="Root" component={Root} />
</Drawer.Navigator>
</NavigationContainer>
);
}
You can find about the navigation to a screen in a nested navigator in docs and you can try this example on Snack
The drawer navigator does not contain headers. Stack navigators must be configured to display headers.
const DrawerNavigator = createDrawerNavigator(
RouteConfigs,
DrawerNavigatorConfig
);
const Root = createStackNavigator({
Main: { screen : DrawerNavigator}
},
{
defaultNavigationOptions : ({ navigation }) => ({
title: "Screen"
})
})
const Stacks = createAppContainer(Root)
export default Stacks;
Since December 2020 you can now use the headerShown: true setting in screenOptions of your Drawer.Navigator to show the header in React Navigation 5.
See more about this issue here: https://github.com/react-navigation/react-navigation/issues/1632
See the commit and comments about the new feature in React Navigation 5 here
https://github.com/react-navigation/react-navigation/commit/dbe961ba5bb243e8da4d889c3c7dd6ed1de287c4
Late reply, But I did it with the below code.
I created separate stack navigators for each screen and after that added all the stack navigators in the drawer navigator.
The good thing is it is fully customized.
Please see my code below.
const WIDTH = Dimensions.get('window').width;
const HomeNavigator = createStackNavigator(
{
Home: Home
},
{
defaultNavigationOptions: ({ navigation }) => {
return {
headerStyle: {
backgroundColor: '#1e89f4'
},
headerTitle: 'Knowledge Woledge',
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
textAlign: 'center',
flex: 1
},
headerLeft: (
<View style={{ paddingLeft: 13 }}>
<FontAwesomeIcon
size={25}
color='#fff'
icon={faBars}
onPress={() => navigation.openDrawer()}
/>
</View>
),
headerRight: <View />
};
}
}
);
const DetailNavigator = createStackNavigator(
{
PostDetail: PostDetail
},
{
defaultNavigationOptions: ({ navigation }) => {
return {
headerStyle: {
backgroundColor: '#1e89f4'
},
headerTitle: () => {
return (
<Text
style={{
color: '#fff',
fontWeight: 'bold',
textAlign: 'center',
flex: 1,
fontSize: 20
}}
>
{navigation.getParam('headerTitle')}
</Text>
);
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
textAlign: 'center',
flex: 1
},
headerLeft: (
<View style={{ paddingLeft: 13 }}>
<FontAwesomeIcon
size={25}
color='#fff'
icon={faArrowLeft}
onPress={() => navigation.goBack(null)}
/>
</View>
),
headerRight: <View />
};
}
}
);
Assigned this in a const
const RouteConfigs = {
Home: {
screen: HomeNavigator,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: ({ tintColor }) => (
<FontAwesomeIcon size={20} color={tintColor} icon={faHome} />
)
}
},
Detail: {
screen: DetailNavigator,
navigationOptions: {
drawerLabel: () => {
return null;
}
}
}
};
And finally, create a drawer navigator with this.
const DrawerNavigatorConfig = {
drawerWidth: WIDTH * 0.75,
drawerType: 'both',
initialRouteName: 'Home'
};
const DrawerNavigator = createDrawerNavigator(
RouteConfigs,
DrawerNavigatorConfig
);
const Stacks = createAppContainer(DrawerNavigator);
export default Stacks;
Related
I am trying deeplinking in React-Native. The code works properly when the app is in the background. But once I remove the app from background and try to launch it using the link in safari. The app is launched with details screen. But I could not find previous (Home) screens in the Navigation Stack. Please find the code below:
/* eslint-disable react-native/no-inline-styles */
import 'react-native-gesture-handler';
import React from 'react';
import {TouchableOpacity, Text, View} from 'react-native';
import {useLinking, NavigationContainer} from '#react-navigation/native';
import {createStackNavigator} from '#react-navigation/stack';
const HomeScreen = ({navigation}) => {
return (
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text>Home Screen</Text>
<TouchableOpacity
onPress={() => {
navigation.navigate('Details', {itemId: 40});
}}>
<Text>Go to Details</Text>
</TouchableOpacity>
</View>
);
};
const DetailScreen = ({route, navigation}) => {
return (
<View
style={{
flex: 1,
alignItems: 'center',
justifyContent: 'center',
}}>
<Text>Details Screen</Text>
<Text>Item Id: {route.params.itemId}</Text>
<TouchableOpacity onPress={() => navigation.goBack()}>
<Text>Go Back</Text>
</TouchableOpacity>
</View>
);
};
const Stack = createStackNavigator();
const App = () => {
const ref = React.useRef();
const {getInitialState} = useLinking(ref, {
prefixes: ['deeplink://'],
config: {
initialRouteName: 'Home',
Home: 'Home',
Details: {
path: 'Details/:itemId',
parse: {
itemId: null,
},
},
},
getPathFromState(state, config) {
console.log(state);
},
});
const [isReady, setIsReady] = React.useState(false);
const [initialState, setInitialState] = React.useState();
React.useEffect(() => {
Promise.race([
getInitialState(),
new Promise((resolve) => setTimeout(resolve, 150)),
])
.catch((e) => {
console.error(e);
})
.then((state) => {
if (state !== undefined) {
setInitialState(state);
}
setIsReady(true);
});
}, [getInitialState]);
if (!isReady) {
return null;
}
return (
<NavigationContainer
fallback={<Text>Loading...</Text>}
initialState={initialState}
ref={ref}>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailScreen} />
</Stack.Navigator>
</NavigationContainer>
);
};
export default App;
Launched the app using "deeplink://Details/86" in Safari.
First, update to latest version of #react-navigation/native and then follow the linking docs: https://reactnavigation.org/docs/configuring-links/
Instead of useLinking, you can pass a linking prop to the NavigationContainer component. Then change your config to following:
const App = () => {
const linking = {
prefixes: ["deeplink://"],
config: {
initialRouteName: "Home",
screens: {
Home: {
path: "home",
},
Details: {
path: "details/:itemId"
}
}
}
};
return (
<NavigationContainer linking={linking} fallback={<Text>Loading...</Text>}>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Details" component={DetailScreen} />
</Stack.Navigator>
</NavigationContainer>
);
};
Then you can open links like deeplink://home or deeplink://details/someid.
I have been following guide at https://reactnavigation.org/docs/3.x/navigating-without-navigation-prop/. However, when I create the Navigation service as per given code snippet and attempt to set the toplevel navigator in my navigator component, It is not navigating to desire screen.
I want to navigate to the brandscreen.js when clicking on brand-logo from homescreen (want tp implement Shop by Brand) but not able to navigate.
App.js
import React, { Component } from 'react';
import { View, Text, StyleSheet,Image} from 'react-native';
import { DrawerItems,
createStackNavigator,
createDrawerNavigator,
createAppContainer,
createSwitchNavigator,
createBottomTabNavigator} from 'react-navigation'
import HomeScreen from './app/screen/HomeScreen';
import ProfileScreen from './app/screen/ProfileScreen';
import Orders from './app/screen/Orders';
import Notification from './app/screen/Notification';
import Logout from './app/screen/Logout';
import EditProfile from './app/screen/EditProfile'
import {Box} from 'react-native-design-utility'
import Address from './app/screen/Address'
import { Container,Header,Content, Body, Icon,Button} from 'native-base';
import BrandScreen from './app/screen/BrandScreen';
import NavigationService from './app/services/NavigationService'
const profileheader={
headerStyle:{
backgroundColor: '#3a455c',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}
class WelcomeScreen extends Component {
render() {
return (
<Box f={1} center>
<Button block light style={styles.btn} onPress={()=>this.props.navigation.navigate('Dashboard')}>
<Text style={{fontSize:16,color:'white',fontWeight:'bold'}}>Login</Text>
</Button>
<Button block light style={styles.btn} onPress={()=>this.props.navigation.navigate('Welcome')}>
<Text style={{fontSize:16,color:'white',fontWeight:'bold'}}>Sign Up</Text>
</Button>
</Box>
);
}
}
const ProfileStack=createStackNavigator({
Profile:{
screen:ProfileScreen,
navigationOptions:({navigation})=>{
return {
headerLeft:<Icon name="md-menu" style={{color:'white',marginLeft:10}} onPress={()=>navigation.toggleDrawer()}/>,
headerStyle:{
backgroundColor: '#3a455c',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}
}
},
EditProfile:{
screen:EditProfile,
navigationOptions:{...profileheader},
}
})
const ProfiletTabNavigator=createBottomTabNavigator({
Profile:{
screen:ProfileStack,
navigationOptions: {
tabBarLabel: 'Profile',
tabBarIcon: () =><Icon name="md-person" size={25} style={{fontSize: 20,paddingTop:5}}/>
}
},
Address:{
screen:Address,
navigationOptions: {
tabBarLabel: 'Saved Address',
tabBarIcon: () =><Icon name="md-bookmark" size={25} style={{fontSize: 20,paddingTop:5}}/>
}
},
},{
navigationOptions:({navigation})=>{
const {routeName}=navigation.state.routes[navigation.state.index]
return {
headerTitle: routeName,
header:null,
headerStyle: {
backgroundColor: '#3a455c',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}
}
})
const ProfileStackNavigator=createStackNavigator({
ProfiletTabNavigator:{
screen:ProfiletTabNavigator,
}
},{
defaultNavigationOptions:({navigation})=>{
return {
headerLeft:<Icon name="md-menu" style={{color:'white',marginLeft:10}} onPress={()=>navigation.toggleDrawer()}/>
}
}
});
const CustomDrawerContentComponent=(props)=>(
<Container>
<Header style={{height:130,backgroundColor:'#3a455c',marginTop:0}}>
<Body>
<Image name='person' style={styles.dImage}
source={require('./app/img/profile-image.jpg')}/>
</Body>
</Header>
<Content>
<DrawerItems {...props}/>
</Content>
</Container>
)
const HomeStack=createStackNavigator({
Home:{
screen:HomeScreen,
navigationOptions: {
header:null,
tabBarLabel: 'Home',
tabBarIcon: () => <Icon name="md-home" size={25} style={{fontSize: 20,paddingTop:5}}/>
},
Brand:BrandScreen
}
})
const AppDrawerNavigator=createDrawerNavigator ({
Home:{
screen:HomeStack,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: () =><Icon name="md-home" size={25} style={{fontSize: 20,paddingTop:5}}/>
}
},
Profile:{
screen:ProfileStackNavigator,
navigationOptions: {
drawerLabel: 'My Account',
drawerIcon: () =><Icon name="md-person" size={25} style={{fontSize: 20,paddingTop:5}}/>
}
},
Orders:Orders,
Notification:Notification,
Logout:Logout,
},{
initialRouteName:'Home',
contentComponent:CustomDrawerContentComponent,
})
const AppSwitchNavigator=createSwitchNavigator({
Welcome:WelcomeScreen,
Dashboard:AppDrawerNavigator,
})
const AppNavigator=createAppContainer(AppSwitchNavigator);
export default class App extends Component {
render() {
return (
<AppNavigator ref={r => NavigationService.setTopLevelNavigator(r)} />
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#2c3e50',
},
dImage:{
height:100,
width:100,
borderRadius:50,
},
btn:{
padding:10,
margin:10,
backgroundColor:'#273746',
borderRadius:4
}
});
NavigationService.js
let _navigator;
function setTopLevelNavigator( navigatorRef ){
_navigator = navigatorRef;
}
function navigate( routeName, params ){
_navigator.dispatch(
NavigationActions.navigate({
routeName,
params
})
);
}
export default {
navigate,
setTopLevelNavigator,
};
BrandCard.js
//import liraries
import React, { Component } from 'react';
import {Image,TouchableOpacity,StyleSheet} from 'react-native'
import {Box,Text} from 'react-native-design-utility'
import NavigationService from '../services/NavigationService';
class BrandCard extends Component {
state={};
handlepress =()=>{
NavigationService.navigate('Brand',{ name: this.props.title});
};
render() {
const {title,image}=this.props;
return(
<TouchableOpacity onPress={this.handlepress} style={{flex:1}}>
<Box center f={1}>
<Box>
<Image source={image} style={{height:100,weight:100,resizeMode:'contain'}}
/>
</Box>
</Box>
</TouchableOpacity>
)
}
}
export default BrandCard;
The only thing you are doing wrong is you are using a route name "brand" which is not declared in your routes.
NavigationService.navigate('Brand',{ name: this.props.title});
Here replace "Brand" with your correct routename.
Hope this helps!
Is there any reason a screen shouldn't be included in two different stack navigators?
I would like it in both stack navigators to have a smooth, in-flow page transition and back button to smoothly go back to the previous page. In example below, ContactScreen appears twice:
const StackOne = createStackNavigator({
About: AboutScreen,
FAQ: FAQScreen,
Contact: ContactScreen
});
const StackTwo = createStackNavigator({
Main: MainScreen,
Details: DetailsScreen
Contact: ContactScreen
});
const MainTabs = createBottomTabNavigator({
TabOne: StackOne,
TabTwo: StackTwo
});
yes, you can use the same screen in different stack navigators . follow this example:
.js file
import React from 'react';
import { Button, Text, View } from 'react-native';
import { Ionicons } from '#expo/vector-icons';
import { createStackNavigator, createBottomTabNavigator, createAppContainer } from 'react-navigation';
class HomeScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
<Button
title="Go to Settings"
onPress={() => this.props.navigation.navigate('Settings')}
/>
<Button
title="Go to Details"
onPress={() => this.props.navigation.navigate('Details')}
/>
</View>
);
}
}
class SettingsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
<Button
title="Go to Home"
onPress={() => this.props.navigation.navigate('Home')}
/>
<Button
title="Go to Details"
onPress={() => this.props.navigation.navigate('Details')}
/>
</View>
);
}
}
class DetailsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details!</Text>
</View>
);
}
}
const HomeStack = createStackNavigator({
Home: { screen: HomeScreen },
Details: { screen: DetailsScreen },
});
const SettingsStack = createStackNavigator({
Settings: { screen: SettingsScreen },
Details: { screen: DetailsScreen },
});
export default createAppContainer(createBottomTabNavigator(
{
Home: { screen: HomeStack },
Settings: { screen: SettingsStack },
},
{
defaultNavigationOptions: ({ navigation }) => ({
tabBarIcon: ({ focused, tintColor }) => {
const { routeName } = navigation.state;
let iconName;
if (routeName === 'Home') {
iconName = `ios-information-circle${focused ? '' : '-outline'}`;
} else if (routeName === 'Settings') {
iconName = `ios-options${focused ? '' : '-outline'}`;
}
// You can return any component that you like here! We usually use an
// icon component from react-native-vector-icons
return <Ionicons name={iconName} size={25} color={tintColor} />;
},
}),
tabBarOptions: {
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
},
}
));
I have created a tabbed view with three tabs based on RNE (React native elements demo app). I had to disable the drawernavigator from the middle tab because it doesn't work to click a link in the drawer and then click the drawer again back to the middle tab view because then it crashes. From the left and right tab it works and I can't understand why this is the case. I'm just trying to open a view but since I am using react navigation it doesn't work. I use a fancy DrawerNavigator, a cool TabNavigator and a nifty StackNavigator instead of keeping it simple and I get error message trying to navigate from the DrawerNavigator to the TabNavigator.
The App.js
/**
* React Native App
*/
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View, Image, Dimensions, AppRegistry
} from 'react-native';
import { DrawerNavigator, DrawerItems,NavigationActions } from 'react-navigation';
import Components from './src/drawer/components';
import Ratings from './src/drawer/ratings';
import Pricing from './src/drawer/pricing';
import Login from './src/drawer/login';
import Profile from './src/drawer/profile';
import Lists from './src/drawer/lists';
const SCREEN_WIDTH = Dimensions.get('window').width;
const CustomDrawerContentComponent = props => {
return(
<View style={{ flex: 1, backgroundColor: '#43484d' }}>
<View
style={{ marginTop: 40, justifyContent: 'center', alignItems: 'center' }}
>
<Image
source={require('./src/images/logo.png')}
style={{ width: SCREEN_WIDTH * 0.57 }}
resizeMode="contain"
/>
</View>
<View style={{marginLeft: 10}}>
<DrawerItems {...props} />
</View>
</View>
)};
const MainRoot = DrawerNavigator(
{
Login: {
path: '/login',
screen: Login
},
Profile: {
path: '/profile',
screen: Profile
},
/* Lists: {
path: '/lists',
screen: Lists
},*/
Components: {
path: '/components',
screen: Components,
},
/* Ratings: {
path: '/ratings',
screen: Ratings,
},*/
Pricing: {
path: '/pricing',
screen: Pricing,
}
},
{
initialRouteName: 'Components',
contentOptions: {
activeTintColor: '#548ff7',
activeBackgroundColor: 'transparent',
inactiveTintColor: '#ffffff',
inactiveBackgroundColor: 'transparent',
labelStyle: {
fontSize: 15,
marginLeft: 0,
},
},
drawerWidth: SCREEN_WIDTH * 0.8,
contentComponent: CustomDrawerContentComponent,
drawerOpenRoute: 'DrawerOpen',
drawerCloseRoute: 'DrawerClose',
drawerToggleRoute: 'DrawerToggle',
}
);
export default MainRoot;
My drawer navigator.
/**
* React Native App
*/
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View, Image, Dimensions, AppRegistry
} from 'react-native';
import { DrawerNavigator, DrawerItems } from 'react-navigation';
import Components from './src/drawer/components';
import Ratings from './src/drawer/ratings';
import Pricing from './src/drawer/pricing';
import Login from './src/drawer/login';
import Profile from './src/drawer/profile';
import Lists from './src/drawer/lists';
const SCREEN_WIDTH = Dimensions.get('window').width;
const CustomDrawerContentComponent = props => (
<View style={{ flex: 1, backgroundColor: '#43484d' }}>
<View
style={{ marginTop: 40, justifyContent: 'center', alignItems: 'center' }}
>
<Image
source={require('./src/images/logo.png')}
style={{ width: SCREEN_WIDTH * 0.57 }}
resizeMode="contain"
/>
</View>
<View style={{marginLeft: 10}}>
<DrawerItems {...props} />
</View>
</View>
);
const CustomDrawerContentComponent2 = (props) => {
const nav = props.nav;
return (<View>
<ScrollView>
<DrawerItems
{...props}
onItemPress = {
({ route, focused }) =>
{
props.onItemPress({ route, focused })
console.log("item pressed");
}
}
/>
</ScrollView>
</View>)
};
const MainRoot = DrawerNavigator(
{
Login: {
path: '/login',
screen: Login
},
Profile: {
path: '/profile',
screen: Profile
},
Lists: {
path: '/lists',
screen: Lists
},
Components: {
path: '/components',
screen: Components,
},
/* Ratings: {
path: '/ratings',
screen: Ratings,
},*/
Pricing: {
path: '/pricing',
screen: Pricing,
}
},
{
initialRouteName: 'Components',
contentOptions: {
activeTintColor: '#548ff7',
activeBackgroundColor: 'transparent',
inactiveTintColor: '#ffffff',
inactiveBackgroundColor: 'transparent',
labelStyle: {
fontSize: 15,
marginLeft: 0,
},
},
drawerWidth: SCREEN_WIDTH * 0.8,
contentComponent: CustomDrawerContentComponent,
drawerOpenRoute: 'DrawerOpen',
drawerCloseRoute: 'DrawerClose',
drawerToggleRoute: 'DrawerToggle',
}
);
export default MainRoot;
My Tab Navigator.
import React from 'react';
import { TabNavigator } from 'react-navigation';
import { Icon } from 'react-native-elements';
import ButtonsTab from '../tabs/buttons';
import ListsTab from '../tabs/lists';
import InputTab from '../tabs/input';
import FontsTab from '../tabs/fonts';
import DetailedTrends from '../views/lists_home'
const Components = TabNavigator(
{
ButtonsTab: {
screen: ButtonsTab,
path: '/buttons',
navigationOptions: {
tabBarLabel: 'Add',
tabBarIcon: ({ tintColor, focused }) => (
<Icon
name={focused ? 'camera' : 'camera'}
size={30}
type="material-community"
color={tintColor}
/>
),
},
},
ListsTab: {
screen: ListsTab,
path: '/lists',
navigationOptions: {
tabBarLabel: 'Ads',
tabBarIcon: ({ tintColor, focused }) => (
<Icon name="list" size={30} type="entypo" color={tintColor} />
),
},
},
/* FontsTab: {
screen: FontsTab,
path: '/fonts',
navigationOptions: {
tabBarLabel: 'On map',
tabBarIcon: ({ tintColor, focused }) => (
<Icon
name={focused ? 'map-marker-outline' : 'map-marker-outline'}
size={30}
type="material-community"
color={tintColor}
/>
),
},
},*/
InputTab: {
screen: InputTab,
path: '/input',
navigationOptions: {
tabBarLabel: 'My activity',
tabBarIcon: ({ tintColor, focused }) => (
<Icon
name={focused ? 'emoticon-cool' : 'emoticon-neutral'}
size={30}
type="material-community"
color={tintColor}
/>
),
},
},
},
{
initialRouteName: 'ListsTab',
animationEnabled: false,
swipeEnabled: true,
// Android's default option displays tabBars on top, but iOS is bottom
tabBarPosition: 'bottom',
tabBarOptions: {
activeTintColor: '#e91e63',
// Android's default showing of icons is false whereas iOS is true
showIcon: true,
},
}
);
Components.navigationOptions = {
drawerLabel: 'Components',
drawerIcon: ({ tintColor }) => (
<Icon
name="settings"
size={30}
iconStyle={{
width: 30,
height: 30
}}
type="material"
color={tintColor}
/>
),
};
export default Components;
If I now press "Components" in the Drawer Navigator to navigate to the components view, my app crashes.
"There is no route defined for key ButtonsTab."
What is the purpose of this error?
How can I troubleshoot this? Why is it complaining about ButtonsTab?
Error: There is no route defined for key ButtonsTab.
Must be one of: 'Home','Lists_Detail'
This error is located at:
in DrawerView (at DrawerNavigator.js:88)
in Unknown (at createNavigator.js:13)
in Navigator (at createNavigationContainer.js:226)
in NavigationContainer (at renderApplication.js:35)
in RCTView (at View.js:78)
in View (at AppContainer.js:102)
in RCTView (at View.js:78)
in View (at AppContainer.js:122)
in AppContainer (at renderApplication.js:34)
getScreenForRouteName
If I add a navigator to lists.js it almost works but still incomprehensible, unnecessary and wrong. Why do they make a framework where you can't navigate between screens?
import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { StackNavigator } from 'react-navigation';
import { Icon } from 'react-native-elements';
import ListsHome from '../views/lists_home';
import ListsDetails from '../views/lists_detail';
import ButtonsTab from '../tabs/buttons';
const ListsTabView = ({ navigation }) => (
<ListsHome banner="Lists" navigation={navigation} />
);
const ListsDetailTabView = ({ navigation }) => (
<ListsDetails banner="Lists Detail" navigation={navigation} />
);
const ListsTab = StackNavigator({
Home: {
screen: ListsTabView,
path: '/',
navigationOptions: ({ navigation }) => ({
title: 'Lists',
headerLeft: (
<Icon
name="menu"
size={30}
type="entypo"
style={{ paddingLeft: 10 }}
onPress={() => navigation.navigate('DrawerOpen')}
/>
),
}),
},
Lists_Detail: {
screen: ListsDetailTabView,
path: 'lists_detail',
navigationOptions: {
title: 'Lists Detail',
},
}, ButtonsTab: {
screen: ListsTabView,
path: '/',
navigationOptions: ({ navigation }) => ({
title: 'Lists',
headerLeft: (
<Icon
name="menu"
size={30}
type="entypo"
style={{ paddingLeft: 10 }}
onPress={() => navigation.navigate('DrawerOpen')}
/>
),
}),
},
});
export default ListsTab;
You can use this sample project which I made to demonstrate StackNavigator, TabNavigator and DrawerNavigator working together.
github.com/paraswatts/DrawerNavigatorReactNative
I hope it helps.
I an trying my hands on react native apps.
I have created an app which as of now has a 3 screen.
Landing Screen, Home Screen & Settings Screen. What I want is that user lands on Landing Screen and there two tabs (Home & Settings) are displayed.
What I have achieved is that user lands on Home Screens and both tabs are displayed but I am unable to make Landing Screen as default page having tabs.
Sample application is available # snack.expo.io
Any help will be appreciated.
App.js
import React from 'react';
import { Text, View } from 'react-native';
import { StackNavigator, TabNavigator } from 'react-navigation'; // 1.0.0-beta.27
import { Icon } from 'react-native-elements'; // 0.19.0
import "#expo/vector-icons"; // 6.3.1
class LandingScreen extends React.Component {
static navigationOptions = {
title: "Landing Screen",
tabBarLabel: "Landing",
tabBarIcon: ({ tintColor }) => <Icon name="menu" size={35} color={tintColor} />,
};
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Landing!</Text>
</View>
);
}
}
class HomeScreen extends React.Component {
static navigationOptions = {
title: "Home Screen",
tabBarLabel: "Home",
tabBarIcon: ({ tintColor }) => <Icon name="list" size={35} color={tintColor} />,
};
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home!</Text>
</View>
);
}
}
class SettingsScreen extends React.Component {
static navigationOptions = {
title: "Settings Screen",
tabBarLabel: "Settings",
tabBarIcon: ({ tintColor }) => <Icon name="loyalty" size={35} color={tintColor} />,
};
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings!</Text>
</View>
);
}
}
const MainTabNav = TabNavigator(
{
Home: {
screen: HomeScreen,
},
Settings: {
screen: SettingsScreen,
},
},
{
tabBarOptions:
{
showIcon: true
}
}
);
const MainStackNav = StackNavigator(
{
Function: {
screen: MainTabNav,
},
Landing: {
screen: LandingScreen,
},
}
);
export default MainStackNav;
I can recommend you this medium article that explain how to setup a very common authentication flow for a react-native app.
It implements two different StackNavigator.
One for the guest, one when you're logged in.
Then you'll find a TabNavigator in which you can also nest others stacknavigator.