Not able to get DrawerNavigator to work in React Navigation - react-native

my code from that entire page is included below and my entire repo is here:
https://github.com/practicia1234/Practicia/commit/d66a23beece1b293c51b4b791f546a2351e6351b
. I am somehow not able to get this drawer navigation to work. For my model, I used the tutorial from here. This is the repo for that tutorial since it has a similar set up as mine, meaning that the first few screens are sign up and login screens and do not have a drawer exposed to the user. I am not sure what i am doing wrong here and would really appreciate if someone could help me a little. Trying to understand drawer navigation for the first time. Thanks!
Here is the error i get:
import React from 'react';
import { Text, Animated, Easing } from 'react-native';
import { StackNavigator, TabNavigator, DrawerNavigator } from 'react-navigation';
// Home scenes
import Home from '../scenes/Home';
import Dashboard from '../scenes/Dashboard';
// Authentication scenes
import Login from '../scenes/authentication/Login';
import SignUpStep from '../scenes/authentication/SignUpStep';
import SelectTeachers from '../scenes/authentication/SelectTeachers';
// import Dashboard from '../components/Dashboard'
// import FeedScreen from '../components/FeedScreen'
import AwardsScreen from '../scenes/award/AwardsScreen';
// import StudentsScreen from '../components/StudentsScreen'
import GameOnScreen from '../scenes/game/GameOnScreen';
// All practice scenes
import AllPractice from '../scenes/practice/AllPractice';
import Practice from '../scenes/practice/Practice';
import PlayingTests from '../scenes/practice/PlayingTests';
import Questions from '../scenes/practice/Questions';
import Individuals from '../scenes/students/individuals';
import FirstScreen from '../scenes/drawer/FirstScreen';
import SecondScreen from '../scenes/drawer/SecondScreen';
import ThirdScreen from '../scenes/drawer/ThirdScreen';
// Group
import Groups from '../scenes/students/groups';
// Upload
import UploadsScreen from '../scenes/upload/UploadsScreen';
import Pending from '../scenes/students/pending';
//import DrawerContainer from '.../components/DrawerContainer'
// const noTransitionConfig = () => ({
// transitionSpec: {
// duration: 0,
// timing: Animated.timing,
// easing: Easing.step0
// }
// });
// Constant for tab menus
const submissionMenu = {
screen: TabNavigator({
All: { screen: AllPractice },
Practice: { screen: Practice },
PlayingTests: { screen: PlayingTests },
Questions: { screen: Questions }
}, {
tabBarPosition: 'top',
flex: 2 / 3,
tabBarOptions: {
activeTintColor: '#33ACDE',
labelStyle: {
fontSize: 12,
},
tabStyle: {
width: 50,
},
}
}
)
};
const studentMenu = {
screen: TabNavigator({
Individuals: { screen: Individuals },
Groups: { screen: Groups },
Pending: { screen: Pending }
}, {
tabBarPosition: 'top',
flex: 2 / 3,
tabBarOptions: {
activeTintColor: '#33ACDE',
labelStyle: {
fontSize: 12,
},
tabStyle: {
width: 50,
},
}
}
)
};
const DrawerStack = DrawerNavigator({
screen1: { screen: FirstScreen },
screen2: { screen: SecondScreen },
screen3: { screen: ThirdScreen },
});
const DrawerNavigation = StackNavigator({
DrawerStack: { screen: DrawerStack }
}, {
headerMode: 'float',
navigationOptions: ({ navigation }) => ({
headerStyle: { backgroundColor: '#4C3E54' },
title: 'Welcome!',
headerTintColor: 'white',
})
});
const LoginStack = StackNavigator({
home: { screen: Home },
signup: { screen: SignUpStep },
login: { screen: Login },
selectTeachers: { screen: SelectTeachers },
dashboard: {
screen: TabNavigator({
Submissions: submissionMenu,
Students: studentMenu,
Awards: { screen: AwardsScreen },
GameOn: { screen: GameOnScreen },
Uploads: { screen: UploadsScreen }
}, {
tabBarPosition: 'bottom',
tabBarOptions: {
activeTintColor: '#33ACDE',
labelStyle: {
fontSize: 12,
},
tabStyle: {
width: 50,
}
}
}),
},
},
{
headerMode: 'float',
navigationOptions: {
headerStyle: { backgroundColor: '#E73536' },
title: 'You are not logged in',
headerTintColor: 'white'
}
});
const navigator = StackNavigator({
loginStack: { screen: LoginStack },
drawerStack: { screen: DrawerNavigation }
}, {
// Default config for all screens
headerMode: 'none',
title: 'Main',
initialRouteName: 'loginStack'
});
export default navigator;

When you execute navigation.navigate('DrawerOpen').
That 'navigation' is not drawer's but StackNavigation's.
If you want to access drawer's navigation, you should call it from children screen in Drawer like FirstScreen, SecondScreen or ThirdScreen.
Execute this.props.navigation.navigate('DrawerOpen') from those Screen.

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) => ...

Modal navigation for certain screens in react-native app

For 3 screens in my app I need to make a modal transition.
For the rest of the screens - I need the default right-to-left transition.
How do I achieve this with different stack navigators?
const AuthStack = createStackNavigator(
{
LogIn: { screen: LogInScreen },
Signup: { screen: SingupScreen },
Welcome: { screen: WelcomeScreen },
CodeVerification: { screen: CodeVerificationScreen },
PasswordSelection: { screen: PasswordSelectionScreen },
RegistrationSuccess: { screen: RegistrationSuccessScreen }
},
{
initialRouteName: 'LogIn'
}
)
const ModalNavigator = createStackNavigator({
ContactInfoEdit: { screen: ContactInfoEditScreen },
DeliveryAddressEdit: { screen: DeliveryAddressEditScreen },
OrderPlacedScreen: { screen: OrderPlacedScreen },
},
{
initialRouteName: 'ContactInfoEdit',
})
const ProductsStack = createStackNavigator(
{
Products: {
screen: ProductsScreen
},
Product: {
screen: ProductScreen
},
ProductBuy: {
screen: ProductBuyScreen
},
OrderConfirm: {
screen: OrderConfirmScreen
},
PlaceOrder: {
screen: PlaceOrderScreen
},
Modal: ModalNavigator
},
{
initialRouteName: 'Products',
mode: 'modal',
}
)
If I set mode: modal it will make all the navigation animations will be modal.
If I remove it, all the navigations will be default (right-to-left)
const ProductsTabStack = createBottomTabNavigator(
{
Orders: { screen: OrdersScreen },
Products: { screen: ProductsStack },
Profile: { screen: ProfileScreen }
},
{
initialRouteName: 'Products',
backBehavior: 'none',
tabBarOptions: {
activeTintColor: '#ffffff',
inactiveTintColor: primaryColor,
activeBackgroundColor: primaryColor,
labelStyle: {
marginBottom: 17,
fontSize: 15,
},
tabStyle: {
shadowColor: primaryColor,
borderWidth: 0.5,
borderColor: primaryColor,
},
},
},
)
export const AppNavigator = createSwitchNavigator({
Auth: AuthStack,
Categories: ProductsTabStack
})
I tried setting mode: modal in the ModalNavigator, but then it took the default parent navigation.
You probably want to try to use StackNavigatorConfig while navigating to that screen this.props.navigation.navigate('ScreenName', params, {mode: 'modal'})
If you want to keep all your transition code in same file as you have right now, you can do the same as what react-navigation is suggesting here
It goes something like that
import { createStackNavigator, StackViewTransitionConfigs } from 'react- navigation';
/* The screens you add to IOS_MODAL_ROUTES will have the modal transition. */
const IOS_MODAL_ROUTES = ['OptionsScreen'];
let dynamicModalTransition = (transitionProps, prevTransitionProps) => {
const isModal = IOS_MODAL_ROUTES.some(
screenName =>
screenName === transitionProps.scene.route.routeName ||
(prevTransitionProps && screenName ===
prevTransitionProps.scene.route.routeName)
)
return StackViewTransitionConfigs.defaultTransitionConfig(
transitionProps,
prevTransitionProps,
isModal
);
};
const HomeStack = createStackNavigator(
{ DetailScreen, HomeScreen, OptionsScreen },
{ initialRouteName: 'HomeScreen', transitionConfig: dynamicModalTransition }
);
OK, found a workaround for custom transitions in 1 StackNavigator using https://www.npmjs.com/package/react-navigation-transitions:
const handleCustomTransition = ({ scenes }) => {
const nextScene = scenes[scenes.length - 1]
if (nextScene.route.routeName === 'ContactInfoEdit')
return fromBottom()
else
return fromRight()
}
const ProductsStack = createStackNavigator(
{
Products: {
screen: ProductsScreen
},
Product: {
screen: ProductScreen
},
ProductBuy: {
screen: ProductBuyScreen
},
OrderConfirm: {
screen: OrderConfirmScreen
},
PlaceOrder: {
screen: PlaceOrderScreen
},
ContactInfoEdit: { screen: ContactInfoEditScreen },
DeliveryAddressEdit: { screen: DeliveryAddressEditScreen },
OrderPlacedScreen: { screen: OrderPlacedScreen },
},
{
initialRouteName: 'Products',
transitionConfig: (nav) => handleCustomTransition(nav)
}
)

The component for route 'AuthLogin' must be a React componet

Hello am developing app in React-Native and got below error :
Error : The component for route 'AuthLogin' must be a React componet.
My Navigation flow is as below :
const AppStack = createStackNavigator(
{
Home: HomeScreen,
ImageDetails: ImageDetailsScreen,
},
{
initialRouteName: 'Home',
/* The header config from HomeScreen is now here */
navigationOptions: {
headerStyle: {
backgroundColor: '#000',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
},
});
const AuthTabStack =createTabNavigator(
{
AuthLogin : AuthStack,
InstaLogin: InstagramLoginScreen,
FacebookLogin: FacebookLoginScreen,
}
);
const AuthStack = createStackNavigator(
{
Login: LoginScreen,
Register: RegisterScreen,
},
{
initialRouteName: 'Login',
/* The header config from HomeScreen is now here */
navigationOptions: {
headerStyle: {
backgroundColor: '#000',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
},
});
const RootStack = createSwitchNavigator(
{
Splash: SplashScreen,//Checking user Authntication
App: AppStack,
Auth: AuthTabStack,
},
{
initialRouteName: 'Splash',
}
);
export default class App extends React.Component {
render() {
return <RootStack />;
}
}
The navigation starts from the RootStack. Contains Splash screen first.
Checking for user login in this screen and accordingly navigating user to either AppStack or AuthTabStack.
Why this error am I getting ?
Is there any issue with TabNavigator ?
Thanks.
EDIT :
==> This is working :
const AuthTabStack = createTabNavigator(
{
//AuthLogin: AuthStack,
Login: LoginScreen,
InstaLogin: InstagramLoginScreen,
FacebookLogin: FacebookLoginScreen
}
);
But, StackNavigator inside TabNavigator has an issue :
const AuthTabStack = createTabNavigator(
{
AuthLogin: AuthStack,
//Login: LoginScreen,
InstaLogin: InstagramLoginScreen,
FacebookLogin: FacebookLoginScreen
}
);
===================================================
You have a space after AuthLogin, AuthLogin : AuthStack, instead of AuthLogin: AuthStack,. This could be causing the error.
If this doesn't fix, try AuthLogin: { screen: AuthStack },

Render both Stack and Tab Navigator

I'm pretty new at react-native, please bear with me. I have a Stack and Tab navigator that both work well but independently. I, however, need them to work together.
const MainTabs = TabNavigator({
Messages: { screen: MessageScreen },
Cards: { screen: CardScreen },
Statements: { screen: StatementScreen },
Profile: { screen: ProfileScreen },
},
{
tabBarOptions: {
activeTintColor: bongzBlue,
inactiveTintColor: 'gray',
},
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',
animationEnabled: false,
swipeEnabled: false,
}
);
export default class App extends Component {
render() {
return (
// <RootStack />
<MainTabs />
);
}
}
Here is a suggestion:
You can nest the StackNavigator in a TabNavigator. So for your specific case, you can make your screens StackNavigators.
For example, your Messages screen can be created like this:
const MessagesStack = StackNavigator({
index: { screen: MessageScreen }
...
})
and then you can use it in your TabNavigator and export that as your main component.
const MainTabs = TabNavigator({
Messages: { screen: MessageStack },
...
},
Hope this helps.

not sure how to implement a drawer navigator in my project

I am trying to implement a drawer navigator in my project. The drawer will appear in all of the following Scenes: AllPractice, Practice, Playing Tests, Question (all tabs)
Individuals, Groups, Pending. (also tabs).
And all of the other main screens: Awards, GameOn, Uploads.
The issue is I don't know where to implement it in my project.
All my navigation is in the navigation folder.
This is the basic code for the drawer:
AppDrawerNavigator = DrawerNavigator({
FirstScreen: { Screen: FirstScreen },
SecondScreen: { Screen: SecondScreen }
});
Here is where all my navigation code is: its in this file
import { StackNavigator, TabNavigator, DrawerNavigator } from 'react-navigation';
// Home scenes
import Home from '../scenes/Home';
// Authentication scenes
import Login from '../scenes/authentication/Login';
import SignUpStep from '../scenes/authentication/SignUpStep';
import SelectTeachers from '../scenes/authentication/SelectTeachers';
// import Dashboard from '../components/Dashboard'
// import FeedScreen from '../components/FeedScreen'
import AwardsScreen from '../scenes/award/AwardsScreen';
// import StudentsScreen from '../components/StudentsScreen'
import GameOnScreen from '../scenes/game/GameOnScreen';
// All practice scenes
import AllPractice from '../scenes/practice/AllPractice';
import Practice from '../scenes/practice/Practice';
import PlayingTests from '../scenes/practice/PlayingTests';
import Questions from '../scenes/practice/Questions';
import Individuals from '../scenes/practice/Individuals';
import FirstScreen from '../scenes/drawer/firstScreen';
import SecondScreen from '../scenes/drawer/secondScreen';
// Group
import Groups from '../scenes/group/Groups';
// Upload
import UploadsScreen from '../scenes/upload/UploadsScreen';
import Pending from '../scenes/upload/Pending';
// Constant for tab menus
const submissionMenu = {
screen: TabNavigator({
All: { screen: AllPractice },
Practice: { screen: Practice },
PlayingTests: { screen: PlayingTests },
Questions: { screen: Questions }
}, {
tabBarPosition: 'top',
flex: 2 / 3,
tabBarOptions: {
activeTintColor: '#33ACDE',
labelStyle: {
fontSize: 12,
},
tabStyle: {
width: 50
},
}
}
)
};
const studentMenu = {
screen: TabNavigator({
Individuals: { screen: Individuals },
Groups: { screen: Groups },
Pending: { screen: Pending }
}, {
tabBarPosition: 'top',
flex: 1 / 2,
tabBarOptions: {
activeTintColor: '#33ACDE',
}
}
)
};
// Navigation defined
const navigator = StackNavigator({
home: { screen: Home },
signup: { screen: SignUpStep },
login: { screen: Login },
selectTeachers: { screen: SelectTeachers },
dashboard: {
screen: TabNavigator({
Submissions: submissionMenu,
Students: studentMenu,
Awards: { screen: AwardsScreen },
GameOn: { screen: GameOnScreen },
Uploads: { screen: UploadsScreen }
}, {
tabBarPosition: 'bottom',
tabBarOptions: {
activeTintColor: '#33ACDE',
}
}),
navigationOptions: {
title: 'PRACTICIA',
headerLeft: null,
headerStyle: {
backgroundColor: '#33ACDE',
},
headerTitleStyle: {
color: 'white'
}
}
}
});
export default navigator;
Drawer Navigation is like a Tab navigation. It means if you want to use a Drawer to offer a user to navigate your app, then forget about the tabs.
Or, if you want to use a drawer just as a controller like you put some buttons on it.
then, it will be like this.
AppDrawerNavigator = DrawerNavigator({
FirstScreen: { Screen: navigator },
});
I put your 'navigator' on the drawer navigation. Then you can use AppDrawerNavigator as a root.
Then, you can use 'contentComponent' in drawerNavigatorOption to put some buttons or view.