Invalid InitialRouteName 'Loading'. Should be one of 'Profile', 'Main', 'History' - react-native

My BottomTabNavigator is working as expected. The problem is that I would like to initially render a page that is outside of the navigator tabs. How could I accomplish this?
import Loading from "./components/Loading.js";
import Profile from "./components/Profile.js";
import History from "./components/History.js";
import Main from "./components/Main.js";
const TabNavigator = createBottomTabNavigator({
Profile: {screen: Profile},
Main: {screen: Locatione},
History: {screen: History},
},
{
initialRouteName: "Loading"
});
export default createAppContainer(TabNavigator);
Before, I was using createStackNavigator, which was working pretty well. Is there any way that I could combine both CreateBottomStackNavigator and createStackNavigator?
const AppNavigator = createStackNavigator(
{
Auth: Auth,
Loading: Loading,
Main:Main,
Locatione:Locatione,
Map: Map,
Contactos: Contactos
},
{
initialRouteName: "Loading"
}
);
const AppContainer = createAppContainer(AppNavigator);
export default function App() {
return <AppContainer />;
}

Yes, you have to add that screen in an navigationStack and name it the inital page, and add the navigation stack to bottomTab navigator.
here im adding the home scren to app stack navigator and this is the inital screen i want to render.
const AppStack = createStackNavigator(
{
HomeScreen: {
screen: Home
},
AirportMeeting:{
screen:AirportMeeting
}
},
{
initialRouteName:"HomeScreen",
}
)
now im adding that appstack , i.e the stack navigator as a tab in the bottomtab navigator by writing Home:AppStack and my notifications and settingscreen are just screens, i.e class componenets
const TabNavigator = createBottomTabNavigator({
Home: AppStack,
Notification:Notifications,
Account: SettingsScreen,
})
and finally im making my tabnavigator as my appcontainer. hence it works
const navigation = createAppContainer(
TabNavigator
);
so similarly you can try for the loadingscreen by adding in the navigation stack and then adding that stack in the bottomTabNavigator nad creating a container of bottomTabNavigator.
Hope it helps. feel free for doubts

Yes, you can do that, what you basically need to is, create a stack navigator as your app container and inside that put bottom tab navigator. Like,
Something like this,
const myTabNavigator = createBottomTabNavigator(
{
Home: { screen: YOUR_HOME },
},
{
contentComponent: SideMenu,
drawerWidth: Dimensions.get('window').width * 0.75
}
)
const RootStack = createStackNavigator({
SplashScreen: {
screen: SplashScreen,
navigationOptions: {
header: null,
},
},
SomeName: {
screen: myTabNavigator,
navigationOptions: {
header: null,
},
},
})
You can add any screen you want to show outside bottom tab navigator.

Related

DrawerNavigator redirects to first route at opening

// AppContainer.js
const AuthNavigator = createStackNavigator(...code);
const DrawerNavigator = createDrawerNavigator(
{
MyAccount: MyAccountScreen,
Home: HomeScreen,
}
);
const AppNavigator = createStackNavigator(
{
Home: HomeScreen,
MyAccount: MyAccountScreen,
}
);
const AppContainer = createAppContainer(
createSwitchNavigator(
{
AuthNavigator,
AppNavigator,
DrawerNavigator,
},
{
initialRouteName: AuthNavigator,
}
)
);
// HomeScreen.js I call:
onPress={() =>
this.props.navigation.dispatch(DrawerActions.openDrawer())
}
It opens the modal, but always goes automatically to MyAccountScreen without touch anything. The expected behaviour it's only open the modal.
Yes, which is actually correct. But you have some flows in understanding how a DrawerNavigator should work. You cannot open the drawer if you're not on the Drawer.
I see that you have HomeScreen defined in 2 Navigators. And I have a feeling that you want to be able to navigate from Home to/from MyAccount using the DrawerNavigator, which means that both those routes have to be inside the DrawerNavigator and you want the HomeScreen to be the first screen that is visible by default.
const DrawerNavigator = createDrawerNavigator(
{
Home: HomeScreen,
MyAccount: MyAccountScreen,
}
);
Which you kind of already have. The misconception that you have is that for your current routes, you don't need the AppNavigator, you could simply rename the above one as AppNavigator and your navigation configuration should look something like this:
const AppNavigator = createDrawerNavigator(
{
Home: HomeScreen,
MyAccount: MyAccountScreen,
}
);
const AppContainer = createAppContainer(
createSwitchNavigator(
{
AuthNavigator,
AppNavigator,
DrawerNavigator,
},
{
initialRouteName: AuthNavigator,
}
)
);
And that's it. Now when you navigate to AppNavigator, the first displayed route will be Home and opening the Drawer will just display the Drawer and won't automatically navigate you to MyAccountScreen.

Use two different Bottom Tab navigator

I am creating a app, where I need to show Bottom Tab Navigator after login.
I know, it is easy with the help of createBottomTabNavigator. But there is little twist:
We have two types of Users. Say "Admin" and "Student". And we need to show different screens stack for both types of users in Bottom Tab Navigator. Both users have same number of tabs, tab icons, etc. Only the screen stack is different.
So my question is, what will be good approach to handle this case:
Should I create two Bottom Tab Navigator using createBottomTabNavigator, and then add both in createSwitchNavigator ?
Or I will create a "Component", and there check, if user type is "Admin", then return "First Bottom Tab Nav" otherwise return "Second" in render function ?
Or any other good approach, please suggest.
I am going with this approach for now (and it is working fine):
Should I create two Bottom Tab Navigator using createBottomTabNavigator, and then add both in createSwitchNavigator ?
Here is the route stack:
Admin stack Navigator:
const AdminStack1 = createStackNavigator(
{
AdminScreen1,
},
{headerMode: 'none', initialRouteName: 'AdminScreen1'},
);
const AdminStack2 = createStackNavigator(
{
AdminScreen2,
},
{headerMode: 'none', initialRouteName: 'AdminScreen2'},
);
Student stack Navigator:
const StudentStack1 = createStackNavigator(
{
StudentScreen1,
},
{headerMode: 'none', initialRouteName: 'StudentScreen1'},
);
const StudentStack2 = createStackNavigator(
{
StudentScreen2,
},
{headerMode: 'none', initialRouteName: 'StudentScreen2'},
);
Admin Tab navigator:
const AdminTabNavigator = createBottomTabNavigator({
Home: AdminStack1,
Calendar: AdminStack2,
},
{
// tabBarOptions
});
Student tab navigator:
const StudentTabNavigator = createBottomTabNavigator({
Home: StudentStack1,
Calendar: StudentStack2,
},
{
// tabBarOptions
});
Drawer navigator:
const DrawerNavigator = createDrawerNavigator(
{
Admin: {
screen: AdminTabNavigator,
},
Student: {
screen: StudentTabNavigator,
},
},
{
contentComponent: Sidebar,
drawerWidth: 310,
drawerType: 'front',
},
);
Main switch navigator:
const AppNavigator = createSwitchNavigator(
{
Login,
Main: DrawerNavigator,
},
{
initialRouteName: 'Login',
},
);
And finally, App container:
const AppContainer = createAppContainer(AppNavigator);
And after login, I have this check:
if (userType === 'Admin') {
this.props.navigation.navigate('AdminScreen1');
} else {
this.props.navigation.navigate('StudentScreen1');
}
So when AdminScreen1 starts, then it automatically starts the Admin tab navigator, as this screen only present in Admin tab navigator. Otherwise it starts the Student tab navigator.
Please suggest, if there are any other better approach.

Stacknavigation inside drawer navigation react native?

have to create a drawer and that drawer I want to use on several screens and inside believe a stack but when it comes to running the app I only get the variable when it comes to creating the stack
const DrawerNav = createDrawerNavigator(
{
screensStack : createStackNavigator({
Welcome: Welcome,
Wellness: Wellness,
Market: Market,
})
},
{
drawerWidth: Dimensions.get("window").width * 0.75,
drawerHeight: Dimensions.get("window").height,
drawerPosition: "left",
contentComponet: DrawerContent
}
)
export default createAppContainer(DrawerNav);
in the drawer only the word screensStack appears
just replace your code with this
const Drawer = createDrawerNavigator(
{
Welcome: { screen: Welcome },
Wellness: { screen: Wellness },
Market: { screen: Market },
},
{
initialRouteName: 'Welcome',
}
)
const AppNavigator = createStackNavigator(
{
Drawer: { screen: Drawer },
},
{
initialRouteName: 'Drawer',
headerMode: 'none',
}
)
const AppContainer = createAppContainer(AppNavigator)
export default () => <AppContainer />
it'll work
The createStackNavigator is located in the drawer. Therefore, when you click a variable in the drawer, you will go to the first screen of the stack navigator.
If you want to make all three variables visible, you need to reposition them.
createAppContainer
createStackNavigator
createDrawerNavigator
Welcome: Welcome,
Wellness: Wellness,
Market: Market,

stackNavigator inside of drawerNavigator's contentComponent

I'm building an app with drawer-navigator. There should be custom side-menu screen which I made by contentComponent, but the problem is I need to make a navigation inside a drawer when the user pressed a button. I tried to pass stackNavigator to customComponent, this returns me "There is no route defined for key ...".
Please, could you help me, make a navigation inside the drawer without closing it.
const tempSN = createStackNavigator(
{
screen: DrawerScreen,
screen2: ProfileSetupScreen
},
{ initialRouteName: "screen" }
);
const DrawerStack = createDrawerNavigator(
{
MainStack: MainStack
},
{
contentComponent: tempSN, // If I pass here DrawerScreen directly, it works
navigationOptions: {
header: null
}
}
);
Can you try the following???
const DrawerStack = createDrawerNavigator(
{
MainStack: MainStack
},
{
contentComponent: drawerComponent,//Your drawer component.Not stack navigator.
navigationOptions: {
header: null
}
}
);
const drawerStack = createStackNavigator(
{
drawerNav: DrawerStack,// Here is the drawer included.
screen: DrawerScreen,
screen2: ProfileSetupScreen
},
);
Add the drawer navigation inside the stack navigation. And when you want to navigate to screen 'screen2', use like this.props.navigation.navigate("screen2")

How to implement Drawer and TabBar in StackNavigator

I always use react-native-router-flux for navigation, but on this project I need to use react-navigation and I got some troubles with it. I need to implement drawer and tabBar inside stack navigator.
Problems:
I use header component from native-base library but i can't open
drawer.
How to use my own customized component for drawer and tabBar?
Maybe I need to chage structure. I will consider any recommendations how to improve structure.
I used version 3 of react-navigation.
My code:
const AppStackNavigator = createStackNavigator({
loginFlow: {
screen: createStackNavigator({
intro: { screen: Intro },
login: { screen: Login },
registration: { screen: Registration },
}),
navigationOptions: {
header: null
}
},
mainFlow: {
screen: createStackNavigator({
MyDrawer: createDrawerNavigator({
Dashboard: {
screen: Home,
},
first: {
screen: first,
},
second: {
screen: second
},
third: {
screen: third
},
last: {
screen: last
}
}),
// settings: { screen: SettingsScreen },
someTab: {
screen: createBottomTabNavigator({
main: { screen: Home },
firsrTab: { screen: Screen1 },
secondTab: { screen: Screen2 },
thirdTab: { screen: Screen3 },
nextTab: { screen: Screen4 }
}),
navigationOptions: {
header: null
},
}
}),
navigationOptions: {
header: null
}
}
});
const AppContainer = createAppContainer(AppStackNavigator);
import React from 'react';
import { Header, Left, Icon, Right } from 'native-base';
const CustomHeader = (props) => {
return(
<Header>
<Left>
<Icon
name='menu'
onPress={() => {this.props.navigation.openDrawer()}}
/>
</Left>
</Header>
)
}
export { CustomHeader }
You might wanna consider the SwitchNavigator for the authentication flow instead of a Stack at the top as it replaces the routes so that you can never navigate back to the login/signup/splash once you get into the application and for accessing Tabs and Drawer inside stack/switch, you can wrap the Drawer inside your top level navigator and tab inside the drawer.
So you root navigation would look like this.
export default RootNavigation = createSwitchNavigator({
LoginScreen: {screen: LoginContainer},
Application: {screen: AppDrawer},
});
Your drawer navigator should be like the following:
const AppDrawer = createDrawerNavigator({
ApplicationTab: {screen: TabBar},
... other screen that you might want to use in drawer navigation.
}, {
contentComponent : (props) => <MyCustomDrawer {...props} />
});
and, Tab Navigator would be,
const TabBar = createBottomTabNavigator({
TabScreen1: {screen: Tab1},
... other tabs...
}, {
tabBarComponent : (props) => <MyTabBar {...props} />
});
If you put each of those navigators in single file then please do declare Tab before Drawer and Drawer before the Switch, else it would give errors.
In my experience, customising drawer navigator is very simple and fruitful but customising tab is not, there aren't proper API doc for the same and community answers are also somewhat misleading.
BUT, with normal use cases and for most of the vivid ones too, you can do your job without needing to override the default one as it is already highly operable and customisable in terms of icons, materialism and each tab exposes its on onPress that can also be easily overriden.
and as you as the drawer is not getting operated from/via the header, then can you please ensure that the navigation prop you are using to operate the drawer open close or toggle action is the one given by drawer ?