how to Implement Stack navigation & drawer navigation together - react-native

Aim- I want to create an app with 3 navigation (2- types)
react-navigation": "^3.3.2
Authloading - basically a loading page which checks for a token in
async storage and decide whether to redirect to AuthStack or
AppStack.
AuthStack - it has login and signup pages .
AppStack - contaons some pages which opens after loging e.g dashboard, profile etc.
What i achieved so far -
I can perform login , sign out, checking at app load if a user is already logged in or not .
What remains-
when user comes at Home / Dashboard i want to have an Side-Menu / Drawer to open on sliding and at button press.
i have tried React navigation 3 docs but I think i am too new to understand that,
Index.js-
import React from 'react';
import { createStackNavigator, createSwitchNavigator, createAppContainer,
createDrawerNavigator } from 'react-navigation';
import Signup from './Screens/Authentication/SignUp';
import SignInScreen from './Screens/Authentication/Login';
import HomeScreen from './Screens/DashBoard/Home';
import AuthLoadingScreen from './Screens/Authentication/AuthLoadingScreen';
const AppStack = createStackNavigator({
Home: HomeScreen,
// Other: OtherScreen
});
const AuthStack = createStackNavigator({
SignIn: SignInScreen,
SignUp: Signup
}, {
headerMode: 'none',
navigationOptions: {
headerVisible: false,
}
});
export default createAppContainer(createSwitchNavigator(
{
AuthLoading: AuthLoadingScreen,
App: AppStack,
Auth: AuthStack,
},
{
initialRouteName: 'AuthLoading',
}
));
const MyDrawerNavigator = createDrawerNavigator({
App: AppStack
});
const MyApp = createAppContainer(MyDrawerNavigator);
But i am not able to open a drawer
Thank you
my index.js file-
import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
my package.Json file-
{
"name": "SM",
"version": "0.0.1",
"private": true,
"scripts": {
"start": "node node_modules/react-native/local-cli/cli.js start",
"test": "jest"
},
"dependencies": {
"react": "16.8.3",
"react-native": "0.59.0",
"react-native-gesture-handler": "^1.1.0",
"react-navigation": "^3.3.2"
},
"devDependencies": {
"#babel/core": "7.3.4",
"#babel/runtime": "7.3.4",
"babel-jest": "24.5.0",
"jest": "24.5.0",
"metro-react-native-babel-preset": "0.53.0",
"react-test-renderer": "16.8.3"
},
"jest": {
"preset": "react-native"
}
}

Try this
import React from 'react';
import { createStackNavigator, createSwitchNavigator, createAppContainer,
createDrawerNavigator } from 'react-navigation';
import Signup from './Screens/Authentication/SignUp';
import SignInScreen from './Screens/Authentication/Login';
import HomeScreen from './Screens/DashBoard/Home';
import AuthLoadingScreen from './Screens/Authentication/AuthLoadingScreen';
const AppStack = createStackNavigator({
Home: MyDrawerNavigator,
// Other: OtherScreen
});
const AuthStack = createStackNavigator({
SignIn: SignInScreen,
SignUp: Signup
}, {
headerMode: 'none',
navigationOptions: {
headerVisible: false,
}
});
export default createAppContainer(createSwitchNavigator(
{
AuthLoading: AuthLoadingScreen,
App: AppStack,
Auth: AuthStack,
},
{
initialRouteName: 'AuthLoading',
}
));
const MyDrawerNavigator = createDrawerNavigator({
Home: HomeScreen
});

Slightly complex example is below where different stack navigators are added to DrawerNavigator and different drawer navigators are added to bottom tab navigator.
import React from "react";
import { Text, View } from "react-native";
import {
createBottomTabNavigator,
createDrawerNavigator,
createStackNavigator,
createAppContainer
} from "react-navigation";
import DetailsScreen from "./uicomponents/DetailsScreen";
import HomeScreen from "./uicomponents/home/HomeScreen";
import CategoriesScreen from "./uicomponents/categories/CategoriesScreen";
import HamburgerIcon from "./uicomponents/HamburgerIcon";
import HamburgerIconR from "./uicomponents/HamburgerIconR";
import SideMenu from "./uicomponents/SideMenu";
import { styles } from "./customstyles/Styles";
import { fromRight } from "react-navigation-transitions";
class SettingsScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Settings!</Text>
</View>
);
}
}
const MainNavigator = createStackNavigator(
{
Home: {
screen: HomeScreen,
navigationOptions: ({ navigation }) => ({
headerTitleStyle: styles.headerTitleStyle,
headerStyle: styles.headerStyle,
headerLeft: <HamburgerIcon navigationProps={navigation} />,
headerRight: <HamburgerIconR navigationProps={navigation} />,
title: `Recipes`,
headerBackTitle: "A much too long text for back button from B to A",
headerBackTitle: null
})
},
Details: {
screen: DetailsScreen,
navigationOptions: () => ({
headerTitleStyle: styles.headerTitleStyle,
headerStyle: styles.headerStyle,
title: `Details`,
headerTintColor: styles.headerTintColor
})
},
Categories: {
screen: CategoriesScreen,
navigationOptions: ({ navigation }) => ({
headerTitleStyle: styles.headerTitleStyle,
headerStyle: styles.headerStyle,
headerRight: <HamburgerIconR navigationProps={navigation} />,
title: `Categories`,
headerTintColor: styles.headerTintColor
})
}
},
{
//initialRouteName: 'Home',
initialRouteName: "Home",
transitionConfig: () => fromRight(500)
}
);
const Drawer = createDrawerNavigator(
{
Home: { screen: MainNavigator },
Regular: { screen: MainNavigator },
Kitchens: { screen: MainNavigator },
Restaurants: { screen: MainNavigator },
Local: { screen: MainNavigator },
Bookmarks: { screen: MainNavigator },
Profile: { screen: MainNavigator },
AboutUs: { screen: MainNavigator },
PrivacyPolicy: { screen: MainNavigator }
},
{
drawerWidth: 300,
contentComponent: SideMenu
}
);
const AppDrawer = createAppContainer(Drawer);
const TabNavigator = createBottomTabNavigator(
{
National: { screen: AppDrawer },
International: { screen: AppDrawer },
Regional: { screen: AppDrawer },
Saved: { screen: AppDrawer }
},
{
tabBarOptions: {
activeTintColor: "yellow",
inactiveTintColor: "white",
style: {
backgroundColor: "#A72428",
paddingBottom:15
}
}
}
);
const App = createAppContainer(TabNavigator);
export default App;
Hope it should help you. !!

Related

Add a submenu to react navigation drawer

I'm using react navigator 4, but I don't seem to find a simple way to add sumbenus to just one item of my drawer. My drawer looks like this:
Current drawer
But my goal is to achive something like this:
Drawer with submenu
How can I add a submenu (or a group) to the drawer navigator?
This is my current navigator code:
import { Image, StyleSheet } from 'react-native';
import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import { createDrawerNavigator } from 'react-navigation-drawer';
import { HiddenItem } from 'react-navigation-header-buttons';
import { createStackNavigator } from 'react-navigation-stack';
import Colors from '../constants/Colors';
import HomeScreen from '../screens/HomeScreen';
import SubItem1Screen from '../screens/SubItem1Screen';
import SubItem2Screen from '../screens/SubItem2Screen';
import OtherScreen from '../screens/OtherScreen';
import LoginNavigator from './LoginNavigator';
const ImageHeader = () => (
<Image
style={styles.imageHeader}
resizeMode="stretch"
source={require('../assets/images/header/background.png')}
/>
);
const styles = StyleSheet.create({
imageHeader: {
...StyleSheet.absoluteFillObject,
width: null,
height: null,
backgroundColor: '#FFF',
},
});
const defaultStackNavigatorOptions = {
headerTintColor: Colors.primary,
headerBackground: ImageHeader,
};
const HomeNavigator = createStackNavigator(
{
Home: {
screen: HomeScreen,
},
},
{
defaultNavigationOptions: defaultStackNavigatorOptions,
}
);
const SubItem1Navigator = createStackNavigator(
{
SubItem1: {
screen: SubItem1Screen,
},
},
{
defaultNavigationOptions: defaultStackNavigatorOptions,
}
);
const SubItem2Navigator = createStackNavigator(
{
SubItem2: {
screen: SubItem2Screen,
},
},
{
defaultNavigationOptions: defaultStackNavigatorOptions,
}
);
const OtherNavigator = createStackNavigator(
{
Other: {
screen: OtherScreen,
},
},
{
defaultNavigationOptions: defaultStackNavigatorOptions,
}
);
const MainNavigator = createDrawerNavigator(
{
Home: {
screen: HomeNavigator,
navigationOptions: {
title: 'Home',
},
},
SubItem1: {
screen: SubItem1Navigator,
},
SubItem2: {
screen: SubItem2Navigator,
},
Other: {
screen: OtherNavigator,
},
},
{
contentOptions: {
activeTintColor: Colors.primary,
labelStyle: {
fontWeight: 'normal',
},
},
}
);
const AppNavigator = createSwitchNavigator({
Login: LoginNavigator,
Main: MainNavigator,
});
export default createAppContainer(AppNavigator);
Need to show Expandable list view inside navigation drawer
This answer above may help you out a bit. A brief summary:
You can try to implement your own navigation drawer as follows. Similar answers are given in the link above.
const DrawerScreen = DrawerNavigator({
Screen1: {
screen: MyHomeScreen
},
Screen2: {
screen: MyNotificationsScreen
}
}, {
headerMode: 'none',
contentComponent: MyDrawer
})
const MyDrawer = (props) => ...

how to use provider for redux to connect it with map state

i have build an full stack drawer and tab navigators in my app.js and now how can i use provider of redux to connect in whole app should i create an new screen and move all components of app.js to that or do something in app.js
const SplashScreen = createStackNavigator({
ScreenWith:{
screen:ScreenWith,
navigationOptions:{
headerTitle:'Logo1',
},
},
});
const HomeStack = createStackNavigator({
Homeview: {
screen: Homeview,
navigationOptions: {
headerTitle: 'Home',
},
},
Beauty: {
screen: Beauty,
navigationOptions: {
headerTitle: 'Beauty',
},
},
ContentPage:{
screen:ContentPage,
navigationOptions:{
headerTitle:'Authenticated',
},
},
Yourcart:{
screen:Yourcart,
navigationOptions:{
headerTitle:'Your Cart',
},
},
SignIn: {
screen: SignIn,
navigationOptions: {
headerTitle: 'SignIn',
},
},
Signup:{
screen:Signup,
navigationOptions:{
headerTitle:'Registered',
},
},
Forgotemail:{
screen:Forgotemail,
navigationOptions:{
headerTitle:'Forgotemail',
}
},
});
const MainTabs = createBottomTabNavigator({
Home: {
screen: HomeStack,
},
Account: {
screen: Account,
},
},
});
const MainDrawer = createDrawerNavigator({
MainTabs : MainTabs,
},{
contentComponent:props =><Drawescreen {...props}/>
});
const AppModalStack = createStackNavigator(
{
App: MainDrawer,
Screentest: Homeview,
},
{
mode: 'modal',
headerMode: 'none',
}
);
const App = createSwitchNavigator({
SplashScreen: {
screen: SplashScreen,
},
App: {
screen: AppModalStack,
},
});
export default createAppContainer(App);
this is my app.js now where i should i add provider to connect with redux ?
Assume that you have export your Container as App
Assume that you have created a class called Main for import your Container App file
This is how you add Provider to your app:
import React from 'react';
import App from '../App'; //Import your app Container
import {Provider} from 'react-redux'; //Import Provider
import store from '../redux/store/store'; //Import your store
const reduxStore = store(); //create redux store
class Main extends React.Component {
render() {
return (
<Provider store={reduxStore}>
<AppContainer />
</Provider>
);
}
}
export default Main;

createDrawerNavigator Is Not Working React Native

I tried lots of things to open drawer but nothing works for me. I do not understand how to combine navigators like I have, one is createStackNavigator and second is createDrawerNavigator. Please check my code if anything goes wrong so let me know otherwise provide me a link or code to implement. thanks
App.js
import React, { Component } from 'react';
import { createAppContainer } from 'react-navigation';
import { createStackNavigator } from 'react-navigation-stack';
import LoginScreen from './src/screens/LoginScreen';
import SignupScreen from './src/screens/SignupScreen';
import DashboardScreen from './src/screens/DashboardScreen';
import CaseListingScreen from './src/screens/CaseListingScreen';
import { createDrawerNavigator, DrawerItems } from "react-navigation-drawer";
import SideBar from './src/SideBar';
const DrawerNavigator = createDrawerNavigator({
Home: {
screen: DashboardScreen,
},
Cases: {
screen: CaseListingScreen,
navigationOptions: {
header: null
}
}
},
{
initialRouteName: 'Home',
}
);
const AppNavigator = createStackNavigator({
Dashboard: {
screen: DashboardScreen,
navigationOptions: {
header: null
}
},
Cases: {
screen: CaseListingScreen,
navigationOptions: {
header: null
}
},
Login: {
screen: LoginScreen,
navigationOptions: {
header: null
}
},
Signup: {
screen: SignupScreen,
navigationOptions: {
header: null
}
}
});
export default createAppContainer(AppNavigator, DrawerNavigator);
DashboardScreen.js
export default class DashboardScreen extends Component {
static navigationOption = {
drawerLabel: 'Home'
}
render() {
return (
<Container>
<Appbar.Header theme={{ colors: { primary: '#b33f3f' } }}>
<Appbar.Action icon="menu" onPress={() => this.props.navigation.navigate('DrawerOpen')} />
<Appbar.Content
title="Manage My Case"
subtitle="Dashboard"
/>
</Appbar.Header>
</Container>
);
}
}
In your export default createAppContainer(AppNavigator, DrawerNavigator); , you should have the drawerNavigator as the app container and not along with App navigator.
createAppContainer contains only 1 arguement , so pass DrawerNavigator in the app container, and if you want to use the stackNavigator inside the drawer navigator just create the drawernavigator as ,
const AppNavigator = createStackNavigator({
Dashboard: {
screen: DashboardScreen,
navigationOptions: {
header: null
}
},
Cases: {
screen: CaseListingScreen,
navigationOptions: {
header: null
}
},
Login: {
screen: LoginScreen,
navigationOptions: {
header: null
}
},
Signup: {
screen: SignupScreen,
navigationOptions: {
header: null
}
}
});
const DrawerNavigator = createDrawerNavigator({
Home: {
screen: DashboardScreen,
},
Cases: {
screen: CaseListingScreen,
navigationOptions: {
header: null
}
},
AppScreen:{
screen:AppNavigator // this is new , im adding stacknavigaoter to your drawer.
}
},
{
initialRouteName: 'Home',
}
);
export default createAppContainer(DrawerNavigator);
Hope that helps, otherwise feel free for doubts.
Mention your drawer navigator inside the stacknavigator just like below,
const myDrawerNavigator = createDrawerNavigator(
{
Home: { screen: YOUR_HOME },
},
{
contentComponent: SideMenu,
drawerWidth: Dimensions.get('window').width * 0.75
}
)
const RootStack = createStackNavigator({
SplashScreen: {
screen: SplashScreen,
navigationOptions: {
header: null,
},
},
SomeName: {
screen: myDrawerNavigator ,
navigationOptions: {
header: null,
},
},
})
Modify the above code as per your screen name and it will works fine...
I hope this helps thanks... :)

Pass parameters between drawer stacks react-navigation

My router setup is as below
import { createAppContainer, createDrawerNavigator, createStackNavigator, createSwitchNavigator } from "react-navigation";
import Home from "./components/Home";
import Search from "./components/Search";
import Map from "./components/Map";
import Login from "./components/Login";
import ForgotPassword from "./components/ForgotPassword";
import SideMenu from "./SideMenu";
const DashboardStack = createStackNavigator(
{
Home: { screen: Home },
Search : {screen : Search}
}
);
const MapStack = createStackNavigator(
{
Map: { screen: Map },
}
);
const AuthStack = createStackNavigator(
{
Login: { screen: Login },
ForgotPassword: { screen: ForgotPassword },
}
);
export const DrawerStack = createDrawerNavigator(
{
Dashboard: { screen: DashboardStack },
Map: { screen: MapStack },
},
{
contentComponent: SideMenu,
drawerWidth: 250
}
);
export const AppNavigator = createStackNavigator(
{
Drawer: { screen: DrawerStack },
Auth: { screen: AuthStack },
},
{
// initialRouteName: "Drawer",
headerMode: 'none',
mode: 'modal',
}
);
export default createAppContainer(DrawerStack);
Everything working fine, just a small issue. When I navigate to search screen from home and then switch to the Map screen with parameters, those parameters are not reaching to the Map screen.
My current setup is at codepan
Your problem is that your MapStack and your Map screen both have the same name, 'Map'.
Just replace the MapStack route to something else like 'MapStack' and you'll get the params.
See here: https://snack.expo.io/SyTFUPZUB
export const DrawerStack = createDrawerNavigator(
{
Dashboard: { screen: DashboardStack },
MapStack: { screen: MapStack },
},
{
contentComponent: SideMenu,
drawerWidth: 250
}
);
#sfratini is right
The issue is indeed "Map" key being present in two places.
So navigation.navigate("Map") will navigate to MapStack.
Navigating to stack means going to current screen of that stack which defaults to initialRouteName or first screen in the stack.
To verify this, add another screen as first screen in MapStack and check the behaviour.
So, solution to your issue is to rename "Map" key to something else, as suggested by #sfratini.
It works fine by just adding map screen to dashboard stack
const DashboardStack = createStackNavigator(
{
Home: { screen: Home },
Search : {screen : Search},
Map: { screen: Map }
}
);
then use
this.props.navigation.getParam('name', 'name is coming')
to get the name params value
here is the code
https://snack.expo.io/HyEFZeyLB
you can reach the parameters in your Map screen like following:
update this :
render() {
return (
<SafeAreaView style={styles.container}>
<Text>Map</Text>
</SafeAreaView>
)
}
to this :
render() {
return (
<SafeAreaView style={styles.container}>
<Text>{this.props.navigation.state.params.name}</Text>
</SafeAreaView>
)
}
and you have to put your Map screen in with home and search Stack like following:
import { createAppContainer, createDrawerNavigator, createStackNavigator,
createSwitchNavigator } from "react-navigation";
import Home from "./components/Home";
import Search from "./components/Search";
import Map from "./components/Map";
import Login from "./components/Login";
import ForgotPassword from "./components/ForgotPassword";
import SideMenu from "./SideMenu";
const DashboardStack = createStackNavigator(
{
Home: { screen: Home },
Search : {screen : Search},
Map: { screen: Map },
}
);
const AuthStack = createStackNavigator(
{
Login: { screen: Login },
ForgotPassword: { screen: ForgotPassword },
}
);
export const DrawerStack = createDrawerNavigator(
{
Dashboard: { screen: DashboardStack },
},
{
contentComponent: SideMenu,
drawerWidth: 250
}
);
export const AppNavigator = createStackNavigator(
{
Drawer: { screen: DrawerStack },
Auth: { screen: AuthStack },
} ,
{
// initialRouteName: "Drawer",
headerMode: 'none',
//mode: 'modal',
}
);
export default createAppContainer(DrawerStack);
the result from your snak :
hope this will help.

Hide tabs in React Native (createBottomTabNavigator)

I am following the documentation of createBottomTabNavigator in React Native, in order to hide the bottom tabs. I have to add the navigationOptions and pass tabBarVisible: false.
Not sure what I am missing:
import React from 'react'
import { StyleSheet, Text, View } from 'react-native'
import AuthScreen from './screens/AuthScreen'
import WelcomeScreen from './screens/WelcomeScreen'
import MapScreen from './screens/MapScreen'
import DeckScreen from './screens/DeckScreen'
import SettingsScreen from './screens/SettingsScreen'
import ReviewScreen from './screens/ReviewScreen'
import { createStackNavigator, createAppContainer, createBottomTabNavigator } from 'react-navigation'
import { Provider } from 'react-redux'
import store from './store'
const TabNavigator = createBottomTabNavigator(
{
Welcome: WelcomeScreen,
Auth: AuthScreen,
Main: {
screen: createBottomTabNavigator({
map: MapScreen,
deck: DeckScreen,
review: {
screen: createStackNavigator({
review: ReviewScreen,
settings: SettingsScreen
})
}
})
}
}, {
navigationOptions: {
tabBarVisible: false,
lazy: true
}
}
)
const AppContainer = createAppContainer(TabNavigator);
export default class App extends React.Component {
render() {
return (
<Provider store={store}>
<AppContainer />
</Provider>
)
}
}
Place tabBarVisible in defaultNavigationOptions, not navigationOptions:
const TabNavigator = createBottomTabNavigator(
{
Welcome: WelcomeScreen,
Auth: AuthScreen,
Main: {
screen: createBottomTabNavigator({
map: MapScreen,
deck: DeckScreen,
review: {
screen: createStackNavigator({
review: ReviewScreen,
settings: SettingsScreen
})
}
})
}
}, {
defaultNavigationOptions: {
tabBarVisible: false
},
navigationOptions: {
lazy: true
}
}
)