Header dose not appearing when using a drawer - reactjs

I am overlapping a StackNavigator on a DrawerNavigator. This is my code
const AppNavigator = StackNavigator({
Home: {
screen: WelcomeContainer,
navigationOptions: ({navigation}) => ({
headerLeft:
<View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems:'center'}}>
<Icon name="menu" color='#5c72b0' size={35} style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems:'center',
paddingLeft:10,
paddingRight:80 }} onPress={ () => navigation.navigate('DrawerOpen') } />
<ChangeLanguage style={{ margin: 30 , padding: 30}} />
</View>,
headerRight:
<HeaderUserInformation />,
})
},
Settings: {
screen: SettingsContainer,
navigationOptions: ({navigation}) => ({
title: navigation.state.params.title
})
},
About: {
screen: About,
navigationOptions: ({navigation}) => ({
title: navigation.state.params.title
})
}
})
const AppDrawer = DrawerNavigator({
Home: {
screen:StackNavigator({
Home: {
screen: WelcomeContainer,
navigationOptions: {
}
}
})
},
Settings: {
screen: StackNavigator({
Category: {
screen: SettingsContainer,
navigationOptions: {
title: "Settings"
}
}
})
}
})
The drawer works properly but there is a problem with the header. This was not the case before I embed the StackNavigator on the DrawerNavigator. The problem is that I customized the header by adding buttons and I am not seeing them anymore on the header. And When I navigate to a new Screen I am not seeing the back button on the header anymore. Do you have an idea what could the problem be?

Related

How to navigate between different nested stacks in react navigation - react native

I am new to react native. I have been using createStackNavigator to be able to navigator throughout my app.
I have created a number of different stacks. Within each stack I have my header code. I have a button in each header that I want to be able to press in order to navigate to another screen, however this screen is within another stack. How would I get access to it?
Here is my code.
export const SearchStack = createStackNavigator({
Search: {
screen: SearchScreen
});
export const HomeStack = createStackNavigator({
Home:
{
screen: HomeScreen,
navigationOptions: ({ navigation }) => ({
headerTitle: 'Home',
headerRight: (
<Icon name="ios-search" color="#fff" size={30} style={{paddingRight: 20}}
onPress={() => navigation.navigate('SearchStack', {}, NavigationActions.navigate({ routeName: 'Search'}))} />
),
headerTitleStyle:{
color: "white",
alignSelf: "center",
fontSize: 20
},
headerStyle:{
backgroundColor: "#404042"
}
}),
},
Listen: {
screen: MainScreen,
navigationOptions: {
headerTitle: 'Listen',
headerRight: (
<Icon name="ios-search" color="#fff" size={30} style={{paddingRight: 20}}
onPress={() => navigation.navigate('Search')} />
),
headerTitleStyle:{
color: "white",
alignSelf: "center",
fontSize: 20
},
headerStyle:{
backgroundColor: "#404042"
}
}
},
},
});
Normally you can call any screen you want as long it is in one of the stacks.

How to implement Log out Functionality in react native

What is the best way to implement the logout functionality in react native in my case when i click the logout button it works fine but next time when i again login and click it it does not work.
import React, {Component} from 'react';
import {AsyncStorage} from 'react-native';
import {url} from '../globals';
import Toast from 'react-native-simple-toast';
class Logout extends Component {
constructor(props) {
super(props);
this.onLogOutPressed = this.onLogOutPressed.bind(this);
}
static navigationOptions = {
header: null,
};
componentWillMount() {
this.onLogOutPressed();
this.props.navigation.addListener('willFocus', this.onLogOutPressed);
}
async onLogOutPressed() {
try {
let response = await fetch(url + '/auth/Logout', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
});
if (response.status >= 200 && response.status < 300) {
console.log('Request Status ', response.status);
let res = await response.json();
console.log('Logout response:', res);
Toast.showWithGravity(res, Toast.LONG, Toast.CENTER);
await AsyncStorage.clear();
this.props.navigation.navigate('login');
} else {
throw 'Enable to parse';
}
} catch (error) {
console.log('error ' + error);
}
}
render() {
return null;
}
}
export default Logout;
And this is the stack navigator and drawer navigation when i click on the logout button for the first time it work fine but second time it move to me last visited page
import React, {Component} from 'react';
import {
StyleSheet,
Dimensions,
SafeAreaView,
View,
Text,
ScrollView,
Image,
} from 'react-native';
import Icon from 'react-native-vector-icons/Ionicons';
import Login from './src/pages/Login';
import Companies from './src/admin/Companies';
import LicensesTable from './src/admin/VerifyLicenses';
import EditLicense from './src/admin/EditLicense';
import ActionEdit from './src/admin/EditLicenseDetails';
import PricingPlan from './src/admin/PricingPlan';
import {createStackNavigator} from 'react-navigation-stack';
import {createDrawerNavigator, DrawerItems} from 'react-navigation-drawer';
import {createSwitchNavigator, createAppContainer} from 'react-navigation';
import AdmDash from './src/admin/AdminDashboard';
import Users from './src/admin/Users';
import Logout from './src/pages/Logout';
global.currentScreenIndex = 0;
export default class App extends Component {
render() {
console.disableYellowBox = true;
return <Draw />;
}
}
const CompaniesStackNavigator = createStackNavigator(
{
CompaniesNavigator: {screen: Companies},
},
{
defaultNavigationOptions: ({navigation}) => {
return {
title: 'Companies',
headerStyle: {backgroundColor: '#1D60D2'},
headerTintColor: 'white',
headerLeft: (
<Icon
style={{paddingLeft: 10, color: 'white'}}
onPress={() => navigation.openDrawer()}
name="md-menu"
size={30}
/>
),
};
},
},
);
const PricingStackNavigator = createStackNavigator(
{
PricingNavigator: {screen: PricingPlan},
},
{
defaultNavigationOptions: ({navigation}) => {
return {
title: 'Pricing Plan',
headerStyle: {backgroundColor: '#1D60D2'},
headerTintColor: 'white',
headerLeft: (
<Icon
style={{paddingLeft: 10, color: 'white'}}
onPress={() => navigation.openDrawer()}
name="md-menu"
size={30}
/>
),
};
},
},
);
const UserStackNavigator = createStackNavigator(
{
UserNavigator: Users,
},
{
defaultNavigationOptions: ({navigation}) => {
return {
title: 'Users',
headerStyle: {backgroundColor: '#1D60D2'},
headerTintColor: 'white',
headerLeft: (
<Icon
style={{paddingLeft: 10, color: 'white'}}
onPress={() => navigation.openDrawer()}
name="md-menu"
size={30}
/>
),
};
},
},
);
const DashboardStackNavigatorAdmin = createStackNavigator(
{
DashboardNavigator: {screen: AdmDash},
},
{
defaultNavigationOptions: ({navigation}) => {
return {
title: 'Dashboard',
headerStyle: {backgroundColor: '#1D60D2'},
headerTintColor: 'white',
headerLeft: (
<Icon
style={{paddingLeft: 10, color: 'white'}}
onPress={() => navigation.openDrawer()}
name="md-menu"
size={30}
/>
),
};
},
},
);
const LicensesStackNavigator = createStackNavigator(
{
LicensesNavigator: {screen: LicensesTable},
},
{
defaultNavigationOptions: ({navigation}) => {
return {
title: 'Verify Licenses',
headerStyle: {backgroundColor: '#1D60D2'},
headerTintColor: 'white',
headerLeft: (
<Icon
style={{paddingLeft: 10, color: 'white'}}
onPress={() => navigation.openDrawer()}
name="md-menu"
size={30}
/>
),
};
},
},
);
const LogoutStackNavigator = createStackNavigator({
LogOutNAvigator: {
screen: Logout,
},
});
const AppNavigator = createStackNavigator({
login: {screen: Login},
EditLicense: {screen: EditLicense},
ActionEdit: {screen: ActionEdit},
},
{
initialRouteName: "login"
});
const AppDrawerNavigator = createDrawerNavigator(
{
login: {
screen: AppNavigator,
navigationOptions: {
drawerLabel: () => null,
},
},
Home: {
screen: DashboardStackNavigatorAdmin,
navigationOptions: {
drawerLabel: () => 'Dashboard',
drawerIcon: ({tintColor}) => (
<Icon name="md-home" style={{fontSize: 24, color: tintColor}} />
),
},
},
Users: {
screen: UserStackNavigator,
navigationOptions: {
drawerIcon: ({tintColor}) => (
<Icon name="md-person" style={{fontSize: 24, color: tintColor}} />
),
},
},
'Pricing Plan':{
screen:PricingStackNavigator,
navigationOptions: {
drawerIcon: ({tintColor}) => (
<Icon name="md-pricetag" style={{fontSize: 24, color: tintColor}} />
),
},
},
Licenses: {
screen: LicensesStackNavigator,
navigationOptions: {
drawerIcon: ({tintColor}) => (
<Icon name="md-briefcase" style={{fontSize: 24, color: tintColor}} />
),
},
},
Companies: {
screen: CompaniesStackNavigator,
navigationOptions: {
drawerIcon: ({tintColor}) => (
<Icon name="md-card" style={{fontSize: 24, color: tintColor}} />
),
},
},
Logout: {
screen: LogoutStackNavigator,
navigationOptions: {
drawerIcon: ({tintColor}) => (
<Icon name="md-log-out" style={{fontSize: 24, color: tintColor}} />
),
},
},
},
{
contentComponent: props => (
<SafeAreaView style={styles.container}>
<View>
<Image
source={require('./src/Images/download.png')}
style={styles.sideMenuProfileIcon}
/>
<Text></Text>
</View>
<ScrollView>
<DrawerItems {...props} />
</ScrollView>
</SafeAreaView>
),
drawerWidth: Dimensions.get('window').width - 130,
},
);
const AppSwitchNavigator = createSwitchNavigator({
Dashboard: {screen: AppDrawerNavigator},
Users: {screen: Users},
Companies: {screen: Companies},
Licenses: {screen: LicensesTable},
});
const Draw = createAppContainer(AppSwitchNavigator);
const styles = StyleSheet.create({
IconS: {
paddingLeft: 10,
},
HeaderStyle: {
backgroundColor: '#1D60D2',
},
container: {
flex: 1,
alignContent: 'center',
justifyContent: 'center',
},
sideMenuContainer: {
width: '100%',
height: '100%',
backgroundColor: '#fff',
alignItems: 'center',
paddingTop: 20,
},
sideMenuProfileIcon: {
resizeMode: 'center',
width: 150,
height: 150,
marginTop: 20,
borderRadius: 75,
alignContent: 'center',
justifyContent: 'center',
},
});
I realise logout in Drawer without conponent, simple overload onItemPress (Typescript example):
<DrawerItems
{...props}
items={props.items.filter((i: any) => i.key !== 'UserProfile')}
getLabel={({route}: Scene) => {
const title = props.descriptors[route.key].options.title;
return (
<Text
style={
route.key !== 'Logout'
? styles.labelStyle
: styles.labelExitStyle
}>
{t(title)}
</Text>
);
}}
//labelStyle={styles.labelStyle}
itemStyle={styles.itemStyle}
iconContainerStyle={styles.iconOpacity}
onItemPress={({route}) => {
if (route.key === 'Logout') {
Alert.alert(
t('Logout'),
t('Are you sure you want to logout?'),
[
{
text: t('Ok'),
onPress: async () => {
const result = await clearProfile();
if (result) {
navigate('Choose');
}
},
},
{text: t('Cancel'), style: 'cancel'},
],
{
cancelable: false,
},
);
} else {
navigate(route.key);
}
}}
/>
It's your Darwer menu:
createDrawerNavigator(
{
...
Logout: {
screen: Choose,
navigationOptions: {
title: 'Logout',
drawerIcon: <Image source={iconRedExit} style={styles.icon} />,
},
},
},
{
initialRouteName: 'Tests',
contentComponent: CustomDrawer,
drawerWidth: width,
},
),
In your CustomDrawer render() you can use DrawerItems from my answer

Drawer Navigator doesnt scroll after making other pages

I made a toggler menu by createDrawerNavigator. at first the menu was working perfectly but after making each page i realized it doesnt scroll verticaly as same before. i dont understand what the problem is. in addtion when each page has error, after clicking on that page the app freezes and menu do scroll! any help? many thanks
.see the menu here https://i.stack.imgur.com/FwoqI.jpg
//imports;
class NavigationDrawerStructure extends React.Component {
toggleDrawer = () => {
this.props.navigationProps.toggleDrawer();
};
render() {
return (
<View style={{ flex: 1 }}>
<TouchableOpacity onPress={this.toggleDrawer.bind(this)}>
<Image
source={require('./image/drawer.png')}
style={{ width: 30, height: 30, marginLeft: 20, marginBottom:10 }}
/>
</TouchableOpacity>
</View>
);
}
}
const firstScreen = createStackNavigator({
Data: {
screen: Data,
navigationOptions: ({ navigation }) => ({
title: 'Data',
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#fff',
},
headerTintColor: 'black',
}),
},
});
const screensDrawerNavigator = createDrawerNavigator(
{
Data: {
screen: firstScreen,
navigationOptions: {
drawerLabel: 'Data',
},
},
},
{
intialRouteName: 'login',
navigationOptions: {
headerStyle : {
backgroundColor: '#f4511e',
},
color: 'white',
},
},
}
)
export default createAppContainer(screensDrawerNavigator);
[1]: https://i.stack.imgur.com/FwoqI.jpg
according the doc's it seems that you are not able to scroll by default because there is no scrollview component added by default. maybe you can try to add a custom-component from this example: https://reactnavigation.org/docs/en/drawer-navigator.html
I think in your case it would be similar to this (see contentComponent):
const screensDrawerNavigator = createDrawerNavigator(
{
Data: {
screen: firstScreen,
navigationOptions: {
drawerLabel: 'Data',
},
},
},
{
intialRouteName: 'login',
contentComponent: props => (
<ScrollView>
<SafeAreaView style={styles.container} forceInset={{ top: 'always', horizontal: 'never' }}>
<DrawerItems {...props} />
</SafeAreaView>
</ScrollView>
),
navigationOptions: {
headerStyle : {
backgroundColor: '#f4511e',
},
color: 'white',
},
},
)

How to go to parent stack navigation screen from child drawer navigation

I have a Drawer navigation and stack navigation on my app.
export const AppDrawerNavigator = createDrawerNavigator(
{
Home: {
screen: Home,
navigationOptions: {
drawerIcon: ({ tintColor }) => (
<Icon name="home" style={{ fontSize: 24, color: tintColor }} />
)
}
},
MyAccount: {
screen: MyAccount,
navigationOptions: {
drawerIcon: ({ tintColor }) => (
<Icon name="paper" style={{ fontSize: 24, color: tintColor }} />
)
}
},
Cashback: {
screen: Cashback,
navigationOptions: {
drawerIcon: ({ tintColor }) => (
<Icon name="pizza" style={{ fontSize: 24, color: tintColor }} />
)
}
},
Settings: {
screen: Settings,
navigationOptions: {
drawerIcon: ({ tintColor }) => (
<Icon name="settings" style={{ fontSize: 24, color: tintColor }} />
)
}
},
Campaigns: {
screen: Campaigns,
navigationOptions: {
drawerIcon: ({ tintColor }) => (
<Icon name="call" style={{ fontSize: 24, color: tintColor }} />
)
}
}
},
{
contentComponent: CustomDrawerComponent,
contentOptions: { activeTintColor: "#60c2a2" }
}
);
export const AppStackNavigator = createStackNavigator(
{
OnBoarding: {
screen: OnBoardingContent
},
Login: {
screen: Login
},
MarchantLogin: {
screen: MarchantLogin
},
OTPScreen: {
screen: OTPScreen
},
Home: {
screen: Home
},
Drawer: {
screen: AppDrawerNavigator
}
},
{
headerMode: "none",
initialRouteName: "Drawer",
navigationOptions: {
headerVisible: false
}
}
);
Then I call this on
render() {
if (this.state.is_verified == "true") {
return <AppStackNavigator />;
} else {
return <OnBoarding />;
}
}
My problem is that when I click on logout inside Drawer button I need to route to OnBoarding component. But how is it possible?
Please help me to solve this or suggest me a better idea because I'm new to this stack. Thankyou.

Drawer header not overlapping StackNavigator header

I am using a DrawerNavigator header and a stack navigation. When the drawer is open, it dose not overlap the header. This is my code
const AppDrawer = DrawerNavigator(
{
Home: {
path: '/',
screen: WelcomeContainer,
},
Category: {
path: '/sent',
screen: CategoryContainer,
},
},
{
initialRouteName: 'Home',
contentOptions: {
activeTintColor: '#e91e63',
},
}
);
const AppNavigator = StackNavigator({
Home: {
screen: AppDrawer,
navigationOptions: ({navigation}) => ({
headerLeft:
<View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems:'center'}}>
<Icon name="menu" color='#5c72b0' size={35} style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems:'center',
paddingLeft:10,
paddingRight:80 }} onPress={ () => navigation.navigate('DrawerOpen') } />
<ChangeLanguage style={{ margin: 30 , padding: 30}} />
</View>,
headerRight:
<HeaderUserInformation />,
})
},
Settings: {
screen: SettingsContainer,
navigationOptions: ({navigation}) => ({
title: navigation.state.params.title
})
},
About: {
screen: About,
navigationOptions: ({navigation}) => ({
title: navigation.state.params.title
})
}
})
I found different threads with the same problem. I tried to move DrawNavigator to the top level, my code become :
const AppNavigator = StackNavigator({
Home: {
screen: WelcomeContainer,
navigationOptions: ({navigation}) => ({
headerLeft:
<View style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems:'center'}}>
<Icon name="menu" color='#5c72b0' size={35} style={{ flexDirection: 'row', justifyContent: 'space-between', alignItems:'center',
paddingLeft:10,
paddingRight:80 }} onPress={ () => navigation.navigate('DrawerOpen') } />
<ChangeLanguage style={{ margin: 30 , padding: 30}} />
</View>,
headerRight:
<HeaderUserInformation />,
})
},
Settings: {
screen: SettingsContainer,
navigationOptions: ({navigation}) => ({
title: navigation.state.params.title
})
},
About: {
screen: About,
navigationOptions: ({navigation}) => ({
title: navigation.state.params.title
})
}
})
const AppDrawer = DrawerNavigator(
{
Home: {
path: '/',
screen: AppNavigator,
},
Category: {
path: '/sent',
screen: CategoryContainer,
},
},
{
initialRouteName: 'Home',
contentOptions: {
activeTintColor: '#e91e63',
},
}
);
Now the drawer is overlapping the header, however the header disappeared from the other components: If I click on an element on the drawer, for example settings, there is no header anymore on this screen. How can I properly fix this overlapping problem?
The DrawerNavigator must be the outermost navigator in order for it to overlap the header, and each screen inside must be declared inside a StackNavigator, like below
const AppDrawer = DrawerNavigator({
Home: {
screen: StackNavigator({
Home: {
screen: WelcomeContainer,
navigationOptions: {
title: "Welcome"
}
}
})
},
Category: {
screen: StackNavigator({
Category: {
screen: CategoryContainer,
navigationOptions: {
title: "Category"
}
}
})
}
})

Resources