DrawerNavigator inside TabNavigator inside StackNavigator in react native - reactjs

I have a login page and after logging user in there is a TabNavigator screen, after clicking one of the TabNavigator icons DrawerNavigator menu should open.
const Tabs = TabNavigator({
Home: {
screen: Home,
navigationOptions: {
tabBarLabel: 'Home',
tabBarIcon: <Image source={require('../assets/images/nav-home.png')} style={{height:25,width:25}}/>,
header: null
}
},
Store: {
screen: Store,
navigationOptions: {
tabBarLabel: 'Store',
tabBarIcon: <Image source={require('../assets/images/nav-store.png')} style={{height:25,width:25}}/>,
header: null
},
},
Other: {
screen: DrawerNav,
navigationOptions: {
tabBarLabel: 'Profile',
tabBarIcon: <Image source={require('../assets/images/nav-profile.png')} style={{height:25,width:25}}/>,
header: null
},
}
},{
initialRouteName: 'Home'
})
const DrawerNav = DrawerNavigator({
Profile: {screen: Profile},
Search: {screen: Search},
})
export const Root = StackNavigator({
LoginScreen: {screen: Login},
Tabs: {screen: Tabs},
},
{
initialRouteName: 'LoginScreen'
}
)
This code gives me an error:
When user clicks Other menu-like screen should slide in from the left which will contain Profile Search and Logout(Like in Slack app) and when user clicks for example Profile screen they will be redirected to that page. How is this possible?

You just move "const DrawerNav" to above "const Tabs".
After that it will work

Related

how to render tabs Navigation and stack navigation at the same time

i am trying to use stack navigation and tab navigation at the same time,i have created a stack navigator and tabs in my app.js files but whenever my app loads they are showing different pages at the same time and i don,t know how to resolve this issue. my app.js code is
import { createStackNavigator, createAppContainer } from 'react-navigation';
import IntroSlides from './src/screens/introslides/introslides';
import Dashboard from './src/screens/dashboard/dashboard';
import InboxScreen from '../screens/inbox/inbox';
import Favourites from '../screens/favourite/favourite';
const MainNavigator = createStackNavigator({
dashboard: { screen: Dashboard },
intro: { screen: IntroSlides },
}, {
headerMode: 'none',
navigationOptions: {
headerVisible: false,
}
});
const TabNavigator = createBottomTabNavigator({
// dashboard: { screen: Dashboard },
Inbox: { screen: InboxScreen },
Favourites: { screen: Favourites }
});
const App = createAppContainer(MainNavigator);
export default App;
when the app loads both the stack shows pages at the same time ,any Help would be appreciated
Here is an example to use tab navigator and stack navigator together:
const Stylelist = StackNavigator({
Login: {
screen: LoginScreen,
navigationOptions: ({ navigation }) => ({
header: null,
}),
},
Register: {
screen: RegisterScreen,
navigationOptions: ({ navigation }) => ({
header: null,
}),
},
Home: {
screen: TabNavigator({
Home: {
screen: HomeScreen,
navigationOptions: ({ navigation }) => ({
title: 'Home',
}),
},
Friends: {
screen: FriendsScreen,
navigationOptions: ({ navigation }) => ({
title: 'My Friends',
}),
},
}),
navigationOptions: ({ navigation }) => ({
title: 'Home',
}),
},
});
export default Stylelist;

How to set an initial screen that is not shown in drawer component?

I want to show an initial screen when the user logs into my react native app.But i don't want to show the screen on the drawer component as i have used drawer component for other screens from react navigation. When the user goes to different screens from the drawer component,i want to make them come to the previous initial screen on pressing back button.
const AppStackNavigator = createStackNavigator({
Map: {
screen: Maps,
navigationOptions: () => ({
header: null
})
},
UpdateProfile: {
screen: UpdateProfileScreen,
navigationOptions: () => ({
header: null
})
},
SearchDetails: {
screen: SearchDetails,
navigationOptions: () => ({
header: null
})
},
})
const AppDrawerNavigator = createDrawerNavigator({
Home: {
screen : AppStackNavigator,
navigationOptions: () => ({
title: `Map`,
drawerIcon: ({tintColor}) => (
<Image source={require('./assets/img/s_logo.png')} style={{height: 24, width: 24}}/>
)
})
},
Search: {
screen: SearchScreen,
navigationOptions: () => ({
title: `Search by`
})
},
Vendor: {
screen: HomeScreen,
navigationOptions: () => ({
title: `Vendor List`,
})
},
Notifications: {
screen: NotificationScreen
},
Events: EventsScreen,
Venue : {
screen: VenueAvailabilityScreen,
navigationOptions: () => ({
title: `Venue Availability`,
})
},
Settings: {
screen: SettingsScreen
}
}, {
drawerPosition: 'left',
contentComponent: customDrawerContentComponent,
drawerOpenRoute: 'DrawerOpen',
drawerCloseRoure: 'DrawerClose',
drawerToggleRoute: 'DrawerToggle',
drawerWidth: 320,
contentOptions: {
activeTintColor: '#fff',
inactiveTintColor: '#030303',
activeBackgroundColor: '#B90066',
inactiveBackgroundColor: '#fff',
itemsContainerStyle: {
marginHorizontal: 10
},
itemStyle: {
height: 40,
borderRadius: 60,
},
activeLabelStyle: {
fontSize: 20,
fontWeight: 'normal'
}
}
})
const AuthStackNavigator = createStackNavigator({
SplashScreen: { screen: SplashScreen },
ModalScreen:{
screen: ModalScreen
},
LocationNotification: {
screen: LocationNotificationScreen,
navigationOptions: () => ({
header: null
})
},
LoginScreen: {
screen : LoginScreen,
navigationOptions: () => ({
header: null
})
},
SignUpScreen: {
screen : SignUpScreen,
navigationOptions: () => ({
header: null
})
},
SignUpStepTwo: {
screen : SignUpStepTwo,
navigationOptions: () => ({
header: null
})
},
ForgotPassword: {
screen: ForgotPassword,
navigationOptions: () => ({
header: null
})
}
})
const AppSwitchNavigator = createSwitchNavigator({
AuthLoadingScreen: AuthLoadingScreen,
Auth: AuthStackNavigator,
App: {
screen: AppDrawerNavigator
}
})
const MyAppDrawer = createAppContainer(AppSwitchNavigator)
class App extends Component {
render() {
return <MyAppDrawer />
}
I want to set the map screen as initial but don't want to show that on drawer. How could i do that?
You can't ... at least it's not easy. You need to create a custom contentcomponent yourself and implement the navigation. Tutorial here. Another approach is to make your appdrawernavigator ,a child of a stacknavigator with the initial screen
const AppSwitchNavigator = createSwitchNavigator({
AuthLoadingScreen: AuthLoadingScreen,
Auth: AuthStackNavigator,
App: MainStackNavigator
})
//the main stack
const MainStackNavigator= createStackNavigator({
InitialScreen: {screen: InitialScreen},
DrawerNav: {screen:AppDrawerNavigator}
},{headerMode: 'none'})

How can I manage two navigation on single page one createstack navigator and second is drawer navigator?

Consider:
export default class App extends React.Component {
render() {
return(
<MyApp />
);
return(
<Navigation />
);
}
const Navigation = createStackNavigator({
Welcome: {
screen: Splash,
navigationOptions: {
header: null
}
},
Login: {
screen: Requesterlogin,
navigationOptions: {
title: "Login",
headerTitleStyle: {
alignSelf: "center",
textAlign: "center",
width: "77%"
},
headerStyle: {
backgroundColor: "#095473"
},
headerTintColor: "white"
}
},
Forgot: {
screen: Forgot,
navigationOptions: {
title: "Forgot Password",
headerTitleStyle: {
alignSelf: "center",
textAlign: "center",
width: "77%"
},
headerStyle: {
backgroundColor: "#095473"
},
headerTintColor: "white"
}
}
});
const MyApp = DrawerNavigator(
{
Home: {
screen: Reqlogin,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: () => (
<Icon
name="home"
size={25}
color="black"
//style={styles.useraccounticon}
/>
),
}
},
Profile: {
screen: Profile_Requester,
navigationOptions: {
drawerLabel: 'Profile',
drawerIcon: () => (
<Icon
name="user-circle"
size={25}
color="black"
//style={styles.useraccounticon}
/>
),
}
},
}
);
In the above code I use two navigation CreateStack navigations used for Navigation.
The Drawer navigator is used for Myapp. But in my case only Myapp is working. How can I return the proper way so both will be working?
It looks like you are trying to implement an authentication flow. You should do that using createSwitchNavigator and nesting your other navigators within that. SwitchNavigator can help you with authentication flows because it handles stuff like making sure you cannot jump to your main app from the Login screen using the Back button.
The idea is, you will have a SwitchNavigator as the parent navigator with two flows: whether the user is signed in or not. The child navigators would be something like Auth and Main. If the user is not signed in, the active navigator would be Auth, which will be a StackNavigator itself. If the user is signed in, the active navigator would be a DrawerNavigator with a stacked StackNavigator.
import { createSwitchNavigator, createStackNavigator, createDrawerNavigator } from 'react-navigation';
const App = createDrawerNavigator({ AppStack: AppStack });
const AppStack = createStackNavigator({
Home: { screen: Reqlogin },
Profile: { screen: Profile_Requester }
});
const Auth = createStackNavigator({
Welcome: { screen: Splash },
Login: { screen: Requesterlogin },
Forgot: { screen: Forgot }
});
export default createSwitchNavigator(
{
AuthLoading: AuthLoadingScreen, // You'll check whether user is logged in or not here
App: AppStack,
Auth: AuthStack,
},
{
initialRouteName: 'AuthLoading',
}
);
For more help, visit this documentation and this article.

Showing TabBar in DrawerNavigator screen

I currently have this structure:
const Tabs = TabNavigator({
Home: {screen: Home},
Store:{screen: Store}
More: {screen: More,
navigationOptions: {
tabBarLabel: 'More',
tabBarIcon: <Entypo name='dots-three-horizontal' size={25}/>,
header: null
},
}
},
{
initialRouteName: 'Home',
tabBarPosition: 'bottom',
navigationOptions: ({ navigation }) => ({
tabBarOnPress: (scene, jumpToIndex) => {
if (scene.route.routeName === "More") {
navigation.navigate('DrawerToggle')
}
else{
jumpToIndex(scene.index);
}
},
}),
},
)
const Drawer = DrawerNavigator(
{
Tabs: {screen: Tabs,
navigationOptions: {
drawerLabel: () => null
}
},
Profile: {screen: Profile},
Search: {screen: Search}
},
{
initialRouteName: 'Tabs',
headerMode: 'none',
drawerPosition: 'right'
}
)
export const Root = StackNavigator(
{
LoginScreen: {screen: Login},
Drawer: {screen: Drawer},
},
{
initialRouteName: 'LoginScreen'
}
)
Everything works great. When I click (for example) 'Profile' the page is loaded normally and when click 'More', drawer menu opens up.
The functionality I would like to achieve is that I would like to show TabBar inside 'Profile' page(DrawerNavigator screen). How is that possible?
const Drawer = DrawerNavigator(
{
Profile: {screen: Tabs},
Search: {screen: Search}
}
You can nest a navigator in another navigator. The Tabs navigator is a component and you can use that component as a "screen" for a different navigator.
A navigator is a component. And a screen must be a component.

When switch between tabs of TabNavigator all of the tabs is mounting

Shows console after switching from the first tab to second:
When it occurs, state of the previous tab is not saving, and the transition to next tab is slow
My route config
const NestedStack1 = StackNavigator({
Tab1Page1: { screen: Tab1Page1 },
},{
navigationOptions: {
headerMode: 'screen'
}
});
const NestedStack2 = StackNavigator({
Tab2Page1: { screen: Tab2Page1 },
},{
navigationOptions: {
headerMode: 'screen'
}
});
const ProfileScreenStack = StackNavigator({
ProfileScreen: { screen: ProfileScreen },
},{
navigationOptions: {
headerMode: 'screen'
}
});
export default TabNavigator({
Tab1: { screen: NestedStack1 },
Tab2: { screen: NestedStack2 },
Tab3: { screen: Tab3 },
Tab4: { screen: Tab4 },
ProfileScreen: { screen: ProfileScreenStack }
},{
tabBarOptions: {
showLabel: false,
activeTintColor: c.BLACK
}
});
How to fix the update of tabs? switching should be quickly with saving state

Resources