I am making a react native app which contains two navigator like below.
const drawerNavigator = createDrawerNavigator(
{
HomePage: { screen: Stack },
History: { screen: History },
Transactions: { screen: Transactions },
Profile: { screen: EditProfile },
Wallet: { screen: Wallet },
ResetPassword: { screen: ResetPassword }
},
{
contentComponent: props => <Drawer { ...props }
/>;
},
{
contentOptions: {
activeTintColor: '#e91e63',
}
});
const RootStack = createStackNavigator({
Splash: { screen: Splash },
Login: { screen: Login },
Register: { screen: Register },
ForgotPassword: { screen: ForgotPassword },
CreateProfile: { screen: CreateProfile },
UploadDocuments: { screen: UploadDocuments },
Home: { screen: drawerNavigator }
}, {
headerMode: 'none',
initialRouteName: 'Splash'
});
Now the problem is that when i logged in successfully then in goes to drawernavigator like this.
this.props.navigation.navigate("Home")
But the problem is that when it goes in stack then it opens drawer by default.How can i make drawer close by default in react native
the problem is that there are 2 routes with name 'Home', one in RootStack and one in drawerNavigator
so every time you navigate to 'Home' both routs get activated. Try changing the name in any one stack
**update for closing drawer
const parent = this.props.navigation.dangerouslyGetParent();
const isDrawerOpen = parent && parent.state && parent.state.isDrawerOpen;
if(isDrawerOpen)
this.props.navigation.closeDrawer();
put this in your componentDidMount()
**for showing data from async storage i did this
class homeDrawerComponent extends Component {
constructor(props) {
super(props);
this.state = {
user: null
};
}
async componentDidMount() {
let user = await appDataStorage.getUser();
await this.setState({ user: user });
}
render(){
const name = this.state.user?this.state.user.firstName+' '+this.state.user.lastName:'';
const email = this.state.user?this.state.user.email:'';
return (
<SafeAreaView>
<View
style={{ height: height * .22, justifyContent: 'flex-start', alignItems: 'flex-start', backgroundColor: 'white',paddingLeft:10,paddingTop:10 }} >
<Image
source={require('./components/images/sj-book-library-logo-drawer.png')}
style={{ width: width * .22, height: width * .25, borderRadius: 50 }} />
<Text style={{ fontWeight: 'bold', color: '#0094FFFF' }}>
{name}
</Text>
<Text style={{ fontWeight: 'bold', color: '#0094FFFF' }}>
{email}
</Text>
</View>
<ScrollView>
<DrawerItems {...this.props} />
</ScrollView>
</SafeAreaView>
)
}
}
Related
I'm trying to send props to all the screen children but only the default screen get the props.
I want to send the props to all the screen of the top navigation. I tried to navigate directly to the tab but it doesn't work either . I don't know what i'm doing wrong.
class RestaurantSummary extends Component {
render () {
return (
<TouchableRipple
onPress={() => this.props.nav.navigation.navigate("Plat", { restaurant: this.props.restaurant,
token: this.props.token, uri: uri})}>
<Card style={styles.container}>
<Card.Cover source={{ uri: uri }} />
<Card.Content style={styles.content}>
<Text style={styles.Text}>{this.props.restaurant.name} - {this.props.restaurant.address} </Text>
</Card.Content>
</Card>
</TouchableRipple>
)
}
}
Here is how i built my navigations . I have a switch navigator which allows me to switch between the app stack and the home stack. And in the App stack i have top bar navigations.
const TabScreen = createMaterialTopTabNavigator(
{
Entrées: { screen: Entrées },
Plat: { screen: Plat },
},
{
tabBarPosition: 'top',
swipeEnabled: true,
animationEnabled: true,
tabBarOptions: {
activeTintColor: '#FFFFFF',
inactiveTintColor: '#F8F8F8',
style: {
backgroundColor: '#633689',
},
labelStyle: {
textAlign: 'center',
},
indicatorStyle: {
borderBottomColor: '#87B56A',
borderBottomWidth: 2,
},
},
}, {
initialRouteName: 'Plat',
}
);
const top = createStackNavigator({
TabScreen: {
screen: TabScreen,
navigationOptions: {
headerStyle: {
backgroundColor: 'transparent',
},
headerTintColor: '#FFFFFF',
title: 'TabExample',
},
},
});
const AuthStack = createStackNavigator({
SignIn: {
screen: SignIn
},
SignUp: {
screen: SignUp
},
SignUpBiss: {
screen: SignUpBiss
}
},{
navigationOptions: {
headerTransparent: true,
},
mode: 'modal',
headerBackTitleVisible: 'true'
})
const AppStack = createStackNavigator({
Home: {
screen: Home
},
tab: top,
RestaurantDetail: {
screen: RestaurantDetail,
navigationOptions:()=>{
return {
tabBarVisible:false,
};
}
},
})
AppStack.navigationOptions = ({ navigation }) => {
let tabBarVisible = true;
if (navigation.state.index > 0) {
tabBarVisible = false; }
return {
tabBarVisible,
}
}
const bottomNav = createBottomTabNavigator({
Home : AppStack,
Logout : {screen: Logout}
})
const Nav = createSwitchNavigator({
App: bottomNav,
Auth: AuthStack
}, {
initialRouteName: 'Auth',
})
export default createAppContainer(Nav)
I saw your problem and I feels your code is little bit in a chaos.
firstly you can change
onPress={() => this.props.nav.navigation.navigate("Plat",
to
onPress={() => this.props.nav.navigation.navigate("TabScreen",
and then try this code in your Tab Screens
this.props.navigation.dangerouslyGetParent().getParam('restaurant')
this.props.navigation.dangerouslyGetParent().getParam('token')
this.props.navigation.dangerouslyGetParent().getParam('uri')
Hope it helps .feel free for doubts
I am trying to create a new app. I have created the side menu. But side menu drawer not working if i am in the same screen.For example in the screenshot i am already in the home screen. Now if i click the home in the side menu there is no action. One more question now the side menu covers the whole screen height. I want to be display between the header and bottom tab navigator. Please help me image
const DashboardTabNavigator = createBottomTabNavigator( {
Home: HomeScreen,
WebMenu: WebMenuScreen,
Settings: SettingsScreen,
},
{
tabBarOptions: {
activeTintColor: 'tomato',
inactiveTintColor: 'gray',
labelStyle: {
fontSize: 15
},
tabStyle: {
justifyContent: 'center'
},
showIcon: false
},
});
//MenuDrawer
export class MenuDrawer extends React.Component {
gotoHome = () => {
this.props.navigation.navigate('Home');
}
gotoWebMenu = () => {
this.props.navigation.navigate('WebMenu');
}
gotoSettings = () => {
this.props.navigation.navigate('Settings');
}
render() {
return(
<View style = {styles.container}>
<Text onPress={this.gotoHome} style = {styles.item} ><Ionicons name="md-home" size={20} /> Home</Text>
<Text onPress={this.gotoWebMenu} style = {styles.item} ><Ionicons name="logo-rss" size={20} /> Web Menu</Text>
<Text onPress={this.gotoSettings} style = {styles.item} ><Ionicons name="md-settings" size={20} /> Settings</Text>
</View>
)
}
}
//side menu
const MyApp = createDrawerNavigator({
Menu: {
screen: DashboardTabNavigator,
},
},
{
contentComponent: MenuDrawer,
drawerPosition: 'right',
drawerWidth:width - width/2
},
{
initialRouteName: 'Login'
});
//screen route
const LoginStack = createStackNavigator({
Login: {
screen: Login
},
Home:{ screen: MyApp},
}, {
initialRouteName: 'Login',
headerMode: 'null'
});
const MyApp1 = createAppContainer(LoginStack);
Try this.
class NavigationDrawerStructure extends Component {
toggleDrawer = () => {
//Props to open/close the drawer
this.props.navigationProps.toggleDrawer();
};
render() {
return (
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity onPress={this.toggleDrawer.bind(this)}>
<Image
source={require('../Img/hamburger.png')}
style={{ width: 25, height: 25, marginLeft: 20, tintColor: '#ffffff' }}
/>
</TouchableOpacity>
</View>
);
}
}
And then use it in this way
const HomeActivity_StackNavigator = createStackNavigator({
Home: {
screen: Main,
navigationOptions: ({ navigation }) => ({
title: 'Dashboard',
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#FF9800'
},
headerTintColor: '#fff'
}),
},
}, {headerLayoutPreset: 'center'});
I am showing username in drawernavigator, but when I logged out and logged in again with a different user, the username is not updating, it's showing old username.
I am also using didFocus Listener but it is also not working please help
import React, { Component } from 'react';
import { View, Image,Text, TouchableOpacity,MenuImage,navigation,AsyncStorage, Alert } from 'react-native';
import {widthPercentageToDP as wp, heightPercentageToDP as hp} from 'react-native-responsive-screen';
import {
createDrawerNavigator,
createStackNavigator,
DrawerItems,
} from 'react-navigation';
import WalkThrow from '../pages/WalkThrow';
import Login from '../pages/Login';
import Register from '../pages/Register';
class NavigationDrawerStructure extends Component {
static propTypes = {
navigation: functionTypes.isRequired,
};
toggleDrawer = async() => {
this.props.navigationProps.openDrawer();
};
render() {
return (
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity onPress={this.toggleDrawer.bind(this)}>
<Image
source={require('../assets/images/menu48.png')}
style={{ width: 25, height: 25, marginLeft: 15 }}
/>
</TouchableOpacity>
</View>
);
}
}
class NavigationImage extends Component {
toggleDrawer = async() => {
this.props.navigationProps.openDrawer();
};
render() {
return (
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity onPress={this.toggleDrawer. bind(this)}>
<Image
source={require('../assets/images/user.png')}
style={{ width: 40, height: 40, marginRight:15 }}
/>
</TouchableOpacity>
</View>
);
}
}
class ShowUserName extends Component{
constructor(props) {
super(props);
this.state = {
getname:''
}
}
componentDidMount= async()=>{
let getname = await AsyncStorage.getItem('userName');
this.setState({getname:getname});
const { navigation } = this.props;
this.focusListener = navigation.addListener("didFocus", async() => {
let getname = await AsyncStorage.getItem('userName');
this.setState({getname:getname});
});
}
render() {
return (
<View>
<Text style={{color:'#fff',fontSize:23,padding:5}}>
{this.state.getname}
</Text>
</View>
);
}
}
const Logout= createStackNavigator({
Register:{
screen:Register,
navigationOptions:{
header: null,
},
},
Login: {
screen: Login,
navigationOptions:{
header: null,
}
},
ForgetPassword: {
screen: ForgetPassword,
navigationOptions:{
header: null,
}
},
initialRouteName: 'WalkThrow',
});
const Profile_StackNavigator = createStackNavigator({
Profile: {
initialRouteName: 'Profile',
screen:ChangeName,
navigationOptions: ({ navigation }) => ({
title: 'Profile',
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#3598db',
shadowOpacity: 0,
elevation: 0,
},
headerTintColor: '#fff',
}),
}
});
const ChangePassword_StackNavigator = createStackNavigator({
ChangePassword: {
initialRouteName: 'WalkThrow',
screen:ChangePassword,
navigationOptions: ({ navigation }) => ({
title: 'Change Password',
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#3598db',
shadowOpacity: 0,
elevation: 0,
},
headerTintColor: '#fff',
}),
},
});
const DashBoard_StackNavigator = createStackNavigator({
WalkThrow: {
screen: WalkThrow,
navigationOptions:{
header: null,
},
},
const DrawerContent = (props) => (
<View>
<View
style={{
backgroundColor: '#3598db',
height: 200,
alignItems: 'center',
justifyContent: 'center',
}}>
<Image
source={require('../assets/images/user.png')}
style={{ width:'36%', height: '50%' }}
/>
<ShowUserName/>
</View>
<DrawerItems {...props} />
</View>
)
export default createDrawerNavigator({
ChangePassword: {
screen: ChangePassword_StackNavigator,
initialRouteName: 'Logout',
navigationOptions: {
drawerLabel: 'Change Password',
drawerIcon: () => (
<Image
source={require('../assets/images/user48.png')}
style={{width: 25, height: 25, }}
/>
)
},
},
Logout: {
screen: Logout,
initialRouteName: 'Logout',
navigationOptions: {
drawerLabel: 'Logout',
drawerIcon: () => (
<Image
source={require('../assets/images/user48.png')}
style={{width: 25, height: 25,}}
/>
)
},
},
},
{
contentComponent: DrawerContent,
});
I am showing username in drawernavigator,but when i logged out and login again with different user the username is not updating,its showing old username.when different user login then show the username for those user
the issue is that this doesn't rerun because the drawer does not unmount
componentDidMount= async()=>{
let getname = await AsyncStorage.getItem('userName');
this.setState({getname:getname});
const { navigation } = this.props;
this.focusListener = navigation.addListener("didFocus", async() => {
let getname = await AsyncStorage.getItem('userName');
this.setState({getname:getname});
});
}
the bigger problem with the architecture of your app is that you' using asyncStorage as your state management it isa huge anti pattern and will make your app really slow and battery draining in the long run.
you have to use some sort of state management ie Context API or redux, then you get your userName straight form the global state it will make the app much faster and solve your problem and probably many others you are experiencing
then your render will look something like this without any need to to set the state again in a lifeCycle Method, you may also need a default depending where you declared the drawer
render() {
return (
<View>
<Text style={{color:'#fff',fontSize:23,padding:5}}>
{this.props.SOMEGLOBALCONTEXTHERE.username || ''}
</Text>
</View>
);
}
Is it possible to disable the modal animation of React Navigation?
class HomeScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
const params = navigation.state.params || {};
return {
headerLeft: (
<Button
onPress={() => navigation.navigate('MyModal')}
title="Info"
color="#fff"
/>
),
/* the rest of this config is unchanged */
};
};
/* render function, etc */
}
class ModalScreen extends React.Component {
render() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text style={{ fontSize: 30 }}>This is a modal!</Text>
<Button
onPress={() => this.props.navigation.goBack()}
title="Dismiss"
/>
</View>
);
}
}
const MainStack = createStackNavigator(
{
Home: {
screen: HomeScreen,
},
Details: {
screen: DetailsScreen,
},
},
{
/* Same configuration as before */
}
);
const RootStack = createStackNavigator(
{
Main: {
screen: MainStack,
},
MyModal: {
screen: ModalScreen,
},
},
{
mode: 'modal',
headerMode: 'none',
}
);
Examples are obtained from React Native official documentation: https://reactnavigation.org/docs/en/modal.html
Solution
Use transitionSpec in transitionConfig for custom screen transition. And make transition duration to Zero.
Official
Example (Not tested)
const ModalNavigator = createStackNavigator(
{
Main: { screen: Main },
Login: { screen: Login },
},
{
headerMode: 'none',
mode: 'modal',
defaultNavigationOptions: {
gesturesEnabled: false,
},
transitionConfig: () => ({
transitionSpec: {
duration: 0,
},
})
...
It's not quite what you want, but you can use the built in Modal component rendered the screen instead. The benefit of doing this is that the Modal component has an animationtype prop that you can set to "none" to get an animation-less modal.
Due to the app being for a different language, I would like for the titles that appear in the drawer to appear in a different language. Currently, they default to the routes that they're set to. So instead of saying "Login" I would like "s'identifier" as an example.
Currently, drawer setup looks like this:
const allDrawerOptions = {
NotificationHistory: { screen: NotificationHistory, },
CameraRegistration: { screen: CameraRegistration, },
Settings: { screen: Settings, },
Info: { screen: Info, }
};
const drawerForNotificationHistory = DrawerNavigator(
allDrawerOptions,
{ initialRouteName: 'NotificationHistory' }
);
const hamburgerIcon = ({ navigation }) => ({
headerLeft:
<TouchableOpacity
onPress={() => navigation.navigate('DrawerToggle')}
style={{
height: '100%',
width: 60,
// marginLeft: 10,
justifyContent: 'center',
alignItems: 'center',
// borderWidth: 1, borderColor: 'red',
}}
>
<Text
style={{
fontFamily: 'FontAwesome',
fontSize: 25,
}}
></Text>
</TouchableOpacity>
});
and my stacknavigator looks like this:
const Navigation = StackNavigator(
{
Splash: { screen: Splash },
Login: { screen: Login },
SignUp: { screen: SignUp },
HomeScreen: { screen: HomeScreen },
Home: { screen: Home },
NotificationHistory: {
screen: drawerForNotificationHistory,
navigationOptions: hamburgerIcon,
},
},
initialRoute: 'HomeScreen'
}
}
They key was to add navigationOptions for each screen inside allDrawerOptions.
so NotificationHistory now looks like
NotificationHistory:
{ screen: NotificationHistory,
navigationOptions: () =>
({
title: '알림 내역'
})
},