React Navigation with nested stack and drawer navigator - react-native

Am trying to develop an simple app, which has auth , drawer , and other stacks ! I am unable to nest each of these.
This is the flow :
--AuthStack
--SplashScreen
--Login
--FogotPassword
--DrawerStack
--DrawerStack
--MainAppStack
--Training
--etc
--MainAppStack
--Home
--screen2
--screen3
etc, For example After auth flow, my main screen would be drawer screen which is Home Screen from mainAppStack. Now, how can i navigate from home to screen2 and screen3 etc ?
I am not getting header, and i couldnt set header title. And while using hardware back its going to Home screen.
Please Guide !
And my navigator setup !
const AppStackNavigator = createStackNavigator({
Home: {
screen: Home,
navigationOptions: {
header: null
}
},
StoreList: {
screen: StoreList,
navigationOptions: {
header: null
}
},
EditSurvey: {
screen: EditSurvey,
navigationOptions: {
header: null
}
},
StoreSurvey: {
screen: StoreSurvey,
navigationOptions: {
header: null
}
},
Competition: {
screen: Competition,
navigationOptions: {
header: null
},
},
Display: {
screen: Display,
navigationOptions: {
header: null
},
},
SurveyCheckList: {
screen: SurveyCheckList,
navigationOptions: {
headerTransparent: true
}
},
});
const DrawerNavigator = createDrawerNavigator({
Dashboard: {
screen: AppStackNavigator,
navigationOptions: {
drawerLabel: "Home",
}
},
Training: {
screen: TrainingList,
navigationOptions: {
drawerLabel: "Training"
}
},
RoutePlan: {
screen: RouteCalendar,
navigationOptions: {
drawerLabel: "Route Plan"
}
}
},
{
contentOptions: {
activeTintColor: '#127CC1',
},
contentComponent: props => <DrawerComponent {...props}/>,
drawerOpenRoute: 'DrawerOpen',
drawerCloseRoute: 'DrawerClose',
drawerToggleRoute: 'DrawerToggle',
navigationOptions : ({navigation}) => {
const { routeName } = navigation.state.routes[navigation.state.index];
const headerTitle = routeName;
return {
headerTitle,
headerLeft: (
<Icon name="md-menu" style={{ marginLeft: 10 }}
onPress={() => navigation.toggleDrawer()}
/>
)
}
}
}
);
const AuthStackNavigator = createStackNavigator(
{
SplashScreen: {
screen: SplashScreen,
navigationOptions: {
headerTransparent: true
}
},
LoginScreen: {
screen: Login,
navigationOptions: {
headerTransparent: true
}
},
Drawer: DrawerNavigator,
});

Related

How to navigate from stack navigator to tab navigator

Once Logged in, a TabNav is present, from 1st tab i navigate to second tab and then i navigate to a screen defined in StackNav now i want to navigate to 3rd Tab in TabNav. How to achieve this? I want to "fetch" data from the server which is not happening coz the "componentDidMount" is not getting called.
I had the same issue when i had to navigate from TabNav to StackNav but i solved it by defining TabNav inside StackNav.
This is my App.js
export class NavigationDrawerStructure extends Component {
toggleDrawer = () => {
this.props.navigationProps.toggleDrawer();
};
render() {
return (
<View style={{ flexDirection: 'row' }}>
</View>
);
}
}
const FirstActivity_StackNavigator = createStackNavigator({
First: {
screen: Screen1,
},
});
const Screen2_StackNavigator = createStackNavigator({
Second: {
screen: Screen2,
},
});
const Screen3_StackNavigator = createStackNavigator({
Third: {
screen: Screen3,
},
});
const TabNavigator = createMaterialTopTabNavigator(
{
Upcoming: { screen: UpcomingScreen },
Accepted: { screen: AcceptedScreen },
Ongoing: { screen: OngoingScreen },
Completed: { screen: CompletedScreen },
},
);
const tabs = createStackNavigator({
Root: {
screen: TabNavigator,
navigationOptions: () => ({
title: `Welcome, John Doe`,
}),
},
});
const AppNavigator = createStackNavigator(
{
login:
{
screen: Login,
navigationOptions: ({ navigation }) => ({
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#fff',
},
headerTintColor: '#fff',
}),
},
login: Login,
tab: tabs,
acceptedTrip: AcceptedTrip,
startTrip: StartTrip,
upload: Upload,
geoLoc: GeoLoc,
ongoingScreen: OngoingScreen
},
{
headerMode: 'none',
navigationOptions: {
headerVisible: false,
}
}
)
const DrawerNavigatorExample = createDrawerNavigator(
{
Screen1: {
screen: AppNavigator,
navigationOptions: {
drawerLabel: 'Login',
},
},
Screen2: {
screen: Screen2_StackNavigator,
navigationOptions: {
drawerLabel: 'Demo Screen 2',
},
},
Screen3: {
screen: Screen3_StackNavigator,
navigationOptions: {
drawerLabel: 'Demo Screen 3',
},
},
Screen4: {
screen: FirstActivity_StackNavigator,
navigationOptions: {
drawerLabel: 'Demo Screen 1',
},
},
},
{
initialRouteName: "Screen1"
}
);
const MyApp = createAppContainer(DrawerNavigatorExample);
class App extends React.Component{
render(){
return <MyApp/>
}
}
export default App
the componentDidMount is not getting called.

Header not working in createSwitchNavigator

My createSwitchNavigator has 3 pages: Login (no header). After login, it sends to the main page where I build my bottom, tab, stack, and drawer navigator.
const MainTabNavigator = createBottomTabNavigator({
Home,
Tenants,
WorkOrders: {
screen: WorkOrders,
navigationOptions: {
title: 'Work Orders'
}
}
}, {
navigationOptions: ({ navigation }) => {
const { routeName } = navigation.state.routes[navigation.state.index];
if (routeName === 'WorkOrders') {
return {
headerTitle: 'Work Orders'
};
}
return {
headerTitle: routeName
};
}
});
const MainStackNavigator = createStackNavigator({
MainTabNavigator
}, {
defaultNavigationOptions: ({ navigation }) => {
return {
headerLeft: (
<Icon
style={{ paddingLeft: 10 }}
onPress={() => navigation.openDrawer()}
name="md-menu"
size={30}
/>
)
};
}
});
const AppDrawerNavigator = createDrawerNavigator({
iRent: {
screen: MainStackNavigator
}
});
const AppSwitchNavigator = createSwitchNavigator({
Login: { screen: Login },
Main: { screen: AppDrawerNavigator },
TenantDetails: {
screen: TenantDetails,
navigationOptions: () => {
return {
headerTitle: 'Tenant'
};
}
},
});
const AppContainer = createAppContainer(AppSwitchNavigator);
From the tenants, I navigate to the TenantDetails page, but in the TenantDetails the header is not showing. Why?
The switch navigator doesn't have a header. You can use a stack navigator instead.
Sample Code:
const AppStackNavigator = createStackNavigator({
Login: {
screen: Login,
navigationOptions:{
header: null // to override the header, because even if you don't specify the header title, a header will be shown.
}
},
Main: {
screen: AppDrawerNavigator,
navigationOptions:{
header: null
}
},
TenantDetails: {
screen: TenantDetails,
navigationOptions: {
headerTitle: 'Tenant',
headerLeft: null // If you want to override the back button, use this.
}
},
});
const AppContainer = createAppContainer(AppStackNavigator);

Logging out to a specific view in react native

I'm a beginner to react native development. At the moment I'm trying to set my navigation for the login logout process. This is my app flow right now Home -> SignIn -> Dashboard. Now when the user clicks the logout button in the dashboard it should go back to Home screen. This works well for the first time, but the problem is, if a user is already logged in, it skips the Home and SignIn and goes straight to Dashboard and if I try to log out from there it actually pushes to new Home view while keeping Dashboard in the stack and when I SignIn it does a pop transition to Dashboard showing the old state data. I did some digging and its said that react doesn't have provision to pop up out to specific view and we may have to use a hack to replace the screen but I'm not sure how to proceed on that. Below is my current code for the stack navigator and logout process.
const Navigator = createStackNavigator({
SplashScreen: {
screen: SplashScreen,
navigationOptions: {
header: null
}
},
Home: {
screen: Home,
navigationOptions: ({ navigation }) => ({
header: null
})
},
SignIn: {
screen: SignIn,
navigationOptions: {
header: null
}
},
Dashboard: {
screen: Dashboard,
navigationOptions: {
header: null
}
}
});
const Drawer = DrawerNavigator(
{ Navigator: { screen: Navigator } },
{ contentComponent: NavigationDrawer }
);
//In Dashboard
logoutUser = () => {
//Perform API call to logout user
this.props.navigation.navigate("Home");
}
You can use the SwitchNavigator,
const DrawerNavigatorExample = createDrawerNavigator({
//Drawer Optons and indexing
Screen1: {
//Title
screen: FirstActivity_StackNavigator,
navigationOptions: {
drawerLabel: 'Demo Screen 1',
drawerIcon: <Image
source={require('../assets/drawer.png')}
style={{ width: 25, height: 25, marginLeft: 5 }}
/>
},
},
Screen2: {
//Title
screen: Screen2_StackNavigator,
navigationOptions: {
drawerLabel: 'Demo Screen 2',
drawerIcon: <Image
source={require('../assets/drawer.png')}
style={{ width: 25, height: 25, marginLeft: 5 }}
/>
},
},
},
{
contentComponent: DrawerContent
});
const onboardingStackNavigator = createStackNavigator( {
Home: {
screen: Login,
navigationOptions: ({ navigation }) => ({
title: "Login",
headerTintColor: 'white',
headerBackTitle: 'Back',
headerStyle: {
backgroundColor: headerBackgroundColor,
},
headerTintColor: headerTintColor,
})
},
Signup: {
screen: Signup,
navigationOptions: ({ navigation }) => ({
title: "SignUp",
headerTintColor: 'white',
headerBackTitle: 'Back',
headerStyle: {
backgroundColor: headerBackgroundColor,
},
})
},},
{
initialRouteName: 'Home',
}
)
const AppNavigator = createAnimatedSwitchNavigator(
{
onboarding:onboardingStackNavigator,
Drawer: {
screen: DrawerNavigatorExample
}
},
{
initialRouteName: 'onboarding',
transition: (
<Transition.In type='fade'></Transition.In>
)
},
);
const AppContainer = createAppContainer(AppNavigator);
export default AppContainer;

React-native back button going to first page

I have a link from "Test" page to "TestDetails" page. but When i click this.props.navigation.goBack(null) on "TestDetails" page , it takes me to the first page which is "Home" instead of "Test". Here's my index.js. I really dont know how arrived at this though. Pls what am I doing wrong
const HomeScreen = createStackNavigator({
Home: {
screen: Home,
navigationOptions: ({navigation}) => ({
})
}
});
const LoginScreen = createStackNavigator({
Home: {
screen: Login,
navigationOptions: ({navigation}) => ({
})
}
});
const SignupScreen = createStackNavigator({
Signup: {
screen: Signup,
navigationOptions: ({navigation}) => ({
})
}
});
const TestsScreen = createStackNavigator({
Tests: {
screen: Tests,
navigationOptions: ({navigation}) => ({
headerTitleStyle: {
fontWeight: '400',
color: '#333',
fontFamily: 'Nunito-Regular',
fontSize: 18
},
headerStyle: {
elevation: 0, //remove shadow on Android
shadowOpacity: 0, //remove shadow on iOS
fontWeight: 400,
},
title: "Consumer tests",
headerLeft:(<Icon.Button name="menu" size={35}
backgroundColor="transparent" color="#2a486c" onPress={() =>
navigation.dispatch(DrawerActions.toggleDrawer())}>
</Icon.Button>
),
})
}
});
const TestDetailsScreen = createStackNavigator({
TestDetails: {
screen: TestDetails,
navigationOptions: ({navigation}) => ({
})
}
});
const SettingsScreen = createStackNavigator({
Settings: {
screen: Settings,
navigationOptions: ({navigation}) => ({
title: "Settings",
headerLeft:(<Icon.Button name="arrow-back" backgroundColor="transparent" color="black" onPress={() => navigation.dismiss()}>
<Text style={{fontSize: 15}}></Text>
</Icon.Button>
),
})
},
});
const drawernav = createDrawerNavigator({
Home: {
screen: HomeScreen,
},
Login: {
screen: LoginScreen,
},
SignUp: {
screen: SignupScreen,
},
Tests: {
screen: TestsScreen,
},
TestDetails: {
screen: TestDetailsScreen,
},
Settings: {
screen: SettingsScreen,
},
},{
contentComponent: SideMenu,
});
AppRegistry.registerComponent(appName, () => createAppContainer(drawernav));
Pls what am I doing wrong
const LoginScreen = createStackNavigator({
Home: {
screen: Login,
navigationOptions: ({navigation}) => ({
})
}
})
why Home: here?
could you add info from console or you are not receiving error or warnings?
Remember always refer official guides https://facebook.github.io/react-native/docs/navigation
I have confirmed the react-native-navigation definition, like below code snippet.
goBack() and goBack(null) same that the same!
back to your question:
like #Michael post, you'd better check your navigation stack fist
export interface NavigationScreenProp<S, P = NavigationParams> {
state: S;
dispatch: NavigationDispatch;
goBack: (routeKey?: string | null) => boolean;
dismiss: () => boolean;
navigate(options: {
routeName:
| string
| {
routeName: string;
params?: NavigationParams;
action?: NavigationNavigateAction;
key?: string;
};
params?: NavigationParams;
action?: NavigationAction;
key?: string;
}): boolean;

How to force drawer to be over header with react navigation

I saw other answers regarding this issue but I can't find solution.
I want to show drawer always above app screen and above header. Instead drawer is always bellow header.
What am I doing wrong here:
const AppNavigation = createStackNavigator(
{
Main: { screen: Main, navigationOptions: {
title: "Main"
} },
Home: { screen: Home, navigationOptions: {
title: "Home"
} }
},
{
initialRouteName: "Main"
}
);
const DrawerNavigation = createDrawerNavigator(
{
Home: Home,
Main: Main
},
{
initialRouteName: "Main"
}
);
App = createStackNavigator({
drawer: {
screen: DrawerNavigation,
},
app: {
screen: AppNavigation
}
}, {
initialRouteName: 'drawer',
navigationOptions: ({navigation}) => ({
headerStyle: {backgroundColor: '#a9a9a9'},
title: 'Welcome!',
headerTintColor: 'white',
headerLeft: <Text onPress={() =>
navigation.dispatch(DrawerActions.toggleDrawer())}>Menu</Text>
})
});
export default () => (
<View style={{ flex: 1 }}>
<App />
</View>
Our app is similar to this. You can make the drawer be over the header with react-navigation if it is the <Root /> component of your app (the one you import into index.js). For example:
export const Root = DrawerNavigator({
Tabs: {
screen: Tabs,
title: 'Tabs'
},
STACK1: {
screen: STACK1,
title: 'STACK1',
},
STACK2: {
screen: STACK2,
title: 'STACK2',
},
});
That will give you something like this: