Header is not visible in react native - react-native

import React, {Component} from 'react';
import {Text, View,TextInput,Button,Alert,KeyboardAvoidingView,ScrollView,Dimensions,TouchableOpacity} from 'react-native';
import AsyncStorage from '#react-native-community/async-storage';
import {BoxShadow} from 'react-native-shadow'
import DropdownAlert from 'react-native-dropdownalert';
import datum from './data';
import Parse from "parse/react-native";
export default class Editprofile extends React.Component {
static navigationOptions = {
title: 'Edit Profile',
headerStyle: {
backgroundColor:'#E8EDF1',
},
headerTintColor:datum.primaryColor,
headerTitleStyle: {
fontWeight: 'bold',
textAlign:"center",
flex:1
},
};
constructor(props) {
super(props)
this.state = {name:"",number:0,windowwidth:Dimensions.get('window').width,windowheight:Dimensions.get('window').height,custid:""};
}
componentDidMount() {
Parse.setAsyncStorage(AsyncStorage);
getData = async () => {
try {
const value = await AsyncStorage.getItem('nameKey')
if(value !== null) {
this.setState({name:await AsyncStorage.getItem('nameKey')
,number: await AsyncStorage.getItem('numberKey')})
const GameScore = Parse.Object.extend("Customer");
const query = new Parse.Query(GameScore);
query.equalTo("phonenumber",parseInt(this.state.number));
const results = await query.find();
for (let i = 0; i < results.length; i++) {
var object = results[i];
this.setState({custid:JSON.stringify(object.id)})
}
}
} catch(e) {
this.dropdown.alertWithType('error', 'Error', 'Error reading values');
}
}
getData();
}
updatedata = async () => {
try {
await AsyncStorage.setItem('nameKey',this.state.name)
await AsyncStorage.setItem('numberKey',this.state.number)
var P = Parse.Object.extend("Customer");
var instance = new P();
var temp=this.state.custid.replace(/['"]+/g, '')
var temptwo=temp.replace(/\//g, "")
instance.id = temptwo.replace(/['"]+/g, '')
instance.set("name",this.state.name);
instance.set("phonenumber",parseInt(this.state.number));
instance.save();
this.dropdown.alertWithType('success', 'Success', 'saved locally ');
} catch (e) {
this.dropdown.alertWithType('error', 'Error', 'Cannot able to create profile');
}
}
render() {
const shadowOpt = {
width:this.state.windowwidth*0.5,
height:this.state.windowheight*0.07,
color:"#000",
border:26,
radius:3,
opacity:0.2,
x:0,
y:3,
style:{marginVertical:5}
}
return (
<View style={{flex:1,flexDirection:'column',justifyContent:'space-evenly',alignItems:'center',backgroundColor:'#E8EDF1'}}>
<BoxShadow setting={shadowOpt}>
<TextInput
placeholderTextColor={datum.placeholderTextColor}
style={{
height: this.state.windowheight*0.07, borderColor:datum.primaryColor, borderWidth: 1,
width:this.state.windowwidth*0.5,backgroundColor:datum.primaryColor, fontWeight: '200',elevation: 2
}}
onChangeText={(value) => this.setState({name:value.trim()})}
value={this.state.name}
/>
</BoxShadow>
<BoxShadow setting={shadowOpt}>
<TextInput
placeholderTextColor={datum.placeholderTextColor}
keyboardType='number-pad'
style={{height: this.state.windowheight*0.07, borderColor:datum.primaryColor, borderWidth: 1,width:this.state.windowwidth*0.5,backgroundColor:datum.primaryColor, fontWeight: '200'}}
onChangeText={(value) => this.setState({number:value})}
value={this.state.number}
/>
</BoxShadow>
<BoxShadow setting={shadowOpt}>
<Button
onPress={()=>this.updatedata()
}
title="Signup"
color={datum.primaryColor}
accessibilityLabel="Learn more about this purple button"
/>
</BoxShadow>
<DropdownAlert ref={ref => this.dropdown = ref} />
</View>
);
}
}
I am using drawer navigation in this project but I don't understand why the header is not visible in my project it is blank, can someone say how to add a header to my component so that I can run out of complaints, I am struggling with this error for past two weeks
react-natvigation is used in the project ,
my app.js
const MyDrawerNavigator = createDrawerNavigator({
entry:{
screen:SIgnup,
navigationOptions: {
drawerLabel: () => null
},
},
Home: {
screen: HOme,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: ({ tintColor }) => (
<Image
source={require("./components/Drawbles/Homeicon.png")}
resizeMode="contain"
style={{ width: 20, height: 20 }}
/>
)
}
},
Editprofile: {
screen: EDit,
navigationOptions: {
drawerLabel: 'Edit Profile',
drawerIcon: ({ tintColor }) => (
<Image
source={require("./components/Drawbles/EditProfile.png")}
resizeMode="contain"
style={{ width: 20, height: 20, tintColor: tintColor }}
/>
)
}
},
Offerrides: {
screen: OFferrides,
navigationOptions: {
drawerLabel: 'Offer Rides',
drawerIcon: ({ tintColor }) => (
<Image
source={require("./components//Drawbles/Offerride.png")}
resizeMode="contain"
style={{ width: 20, height: 20 }}
/>
)
}
},
Paymentmethod: {
screen: PAymentmethod,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: ({ tintColor }) => (
<Image
source={require("./components/Drawbles/Paymentmethod.png")}
resizeMode="contain"
style={{ width: 20, height: 20 }}
/>
)
}
},
Otp: {
screen: OTp,
navigationOptions: {
drawerLabel: () => null //hide header if not needed so whole screen slide
},
}
},{});
const MyApp = createAppContainer(MyDrawerNavigator);
export default MyApp;

Drawer navigation by default doesn't display the header,it just display the drawing menu. As it is you can open the drawer by sliding right,if you want to open it with a header you have to do a component and use it on screens you want. Heres a nice example of headers: https://react-native-training.github.io/react-native-elements/docs/header.html

Try change this:
static navigationOptions = {
...props...
}
To this:
static navigationOptions = () => {
return {
...props...
}
}

Related

React native navigate throwing error 'Can not read property 'navigate' of undefined

I am running a code that displays menu of various dishes where users can press one of the dishes they will be taken to "Dishdetail" screen where read about the dish. The problem is when we get to the point where we click the app is using navigate but the app is throwing some error message that says the "TypeError: Can not read Property 'navigate' of undefined". You can see the code I have it declared in the code below.
MainComponent.js
import React, { Component } from 'react' ;
import Menu from './MenuComponent' ;
import { View, Image, StyleSheet, ScrollView, Text,Platform } from 'react-native'
//import { Platform } from '#unimodules/core';
import Home from './HomeComponent';
import Dishdetail from './DishdetailComponent' ;
import Contact from './ContactComponent' ;
import About from './AboutComponent';
import { Icon } from 'react-native-elements';
import { createStackNavigator, createDrawerNavigator,SafeAreaView,DrawerItems } from 'react-navigation';
//1. ActionCreators import
import { fetchDishes, fetchComments, fetchPromos, fetchLeaders} from '../redux/ActionCreators';
//1.import to connect to redux
import { connect } from 'react-redux';
import {baseUrl } from '../shared/baseUrl';
//2.leaders state from store
const mapStateToProps = state => {
return {
}
}
//2. get the actions creators
const mapDispatchToProps = dispatch => ({
fetchDishes: () => {dispatch(fetchDishes())},
fetchComments:() => {dispatch(fetchComments())},
fetchPromos: () => {dispatch(fetchPromos())},
fetchLeaders: () => {dispatch(fetchLeaders())}
})
//() => <Menu/>
const MenuNavigator = createStackNavigator({
Menu: { screen: () => <Menu/>,
navigationOptions: ({ navigation }) => ({
headerLeft: <Icon name='menu' size={24}
color='white'
onPress={ () => navigation.toggleDrawer()}
/>
})
},
Dishdetail: { screen: () => <Dishdetail/> }
},
{
initialRouteName: 'Menu',
navigationOptions: {
headerStyle: {
backgroundColor: '#512DA8'
},
headerTintColor: '#fff',
headerTitleStyle: {
color: '#fff'
}
}
})
//Create stacknavigator for Home Component
const HomeNavigator = createStackNavigator({
Home: { screen: () => <Home/> }
},
{
navigationOptions: ({ navigation }) => ({
headerStyle: {
backgroundColor: '#512DA8'
},
headerTintColor: '#fff',
headerTitleStyle: {
color: '#fff'
},
headerLeft: <Icon name='menu' size={24}
color='white'
onPress={() => navigation.toggleDrawer()}
/>
})
});
//Create stacknavigator for Contact Component
const ContactNavigator = createStackNavigator({
Contact: { screen: () => <Contact/>}
},
{
navigationOptions: ({ navigation }) => ({
headerStyle: {
backgroundColor: '#512DA8'
},
headerTintColor: '#fff',
headerTitleStyle: {
color: '#fff'
},
headerLeft: <Icon name='menu' size={24}
color='white'
onPress={() => navigation.toggleDrawer()}
/>
})
});
//Create stacknavigator for About Component
const AboutNavigator = createStackNavigator({
About: { screen: () => <About />}
},
{
navigationOptions: ({ navigation }) => ({
headerStyle: {
backgroundColor: '#512DA8'
},
headerTintColor: '#fff',
headerTitleStyle: {
color: '#fff'
},
headerLeft: <Icon name='menu' size={24}
color='white'
onPress={() => navigation.toggleDrawer()}
/>
})
});
const CustomDrawerContentComponent = (props) => (
<ScrollView>
<SafeAreaView style= {StyleSheet.container}
forceInset={{ top: 'always', horizontal: 'never'}} >
<View style={styles.drawerHeader} >
<View style={{flex:1}} >
<Image source={require('./images/logo.png')}
style={styles.drawerImage} />
</View>
<View style={{flex: 2}} >
<Text style={styles.drawerHeaderText} >Ristorante Con Fusion</Text>
</View>
</View>
<DrawerItems {...props } />
</SafeAreaView>
</ScrollView>
)
//Create drawerNavigator for all Components
// Modified
const MainNavigator = createDrawerNavigator({
Home:
{
screen: HomeNavigator,
navigationOptions: {
title: 'Home',
drawerLabel: 'Home',
drawerIcon: ({ tintColor }) => (
<Icon
name='home'
type='font-awesome'
size={24}
color={tintColor}
/>
)
}
},
About:
{
screen: AboutNavigator,
navigationOptions: {
title: 'About Us',
drawerLabel: 'About Us',
drawerIcon: ({ tintColor }) => (
<Icon
name='info-cirlce'
type='font-awesome'
size={24}
color={tintColor}
/>
)
}
},
Menu:
{
screen: MenuNavigator,
navigationOptions: {
title: 'Menu',
drawerLabel: 'Menu',
drawerIcon: ({ tintColor }) => (
<Icon
name='list'
type='font-awesome'
size={24}
color={tintColor}
/>
)
}
},
Contact:
{
screen: ContactNavigator,
navigationOptions: {
title: 'Contact Us',
drawerLabel: 'Contact Us',
drawerIcon: ({ tintColor }) => (
<Icon
name='address-card'
type='font-awesome'
size={22}
color={tintColor}
/>
)
}
}
},{
drawerBackgroundColor: '#D1C4E9',
contentComponent: CustomDrawerContentComponent
})
class Main extends Component {
//3. Actioncreators to be loaded by componentDidMount()
componentDidMount() {
this.props.fetchDishes();
this.props.fetchComments();
this.props.fetchPromos();
this.props.fetchLeaders();
}
//<Menu />:Display all dishes and when user clicks one of them
//<Dishdetail>: filter the selectedDish and display its detail underneath
render() {
return (
<View style={{flex: 1, paddingTop: Platform.OS === 'ios' ? 0: Expo.Constants.statusBarHeight }}>
<MainNavigator />
</View>
)
}
}
const styles = StyleSheet.create ({
container: {
flex: 1
},
drawerHeader:{
backgroundColor: '#512DA8',
height: 140,
alignItems: 'center',
justifyContent: 'center',
flex: 1,
flexDirection: 'row'
},
drawerHeaderText: {
color: 'white',
fontSize: 24,
fontWeight: 'bold'
},
drawerImage: {
margin: 10,
width: 80,
height: 60
}
})
export default connect(mapStateToProps, mapDispatchToProps)(Main);
MenuComponent.js
import React, { Component } from 'react' ;
import { FlatList } from 'react-native' ;
import { Tile } from 'react-native-elements' ;
//import { DISHES} from '../shared/dishes';
//1.import to connect to redux
import { connect } from 'react-redux';
import { baseUrl } from '../shared/baseUrl';
//2.leaders state from store
const mapStateToProps = state => {
return {
dishes: state.dishes
}
}
//functional component
class Menu extends Component {
constructor(props) {
super(props);
}
//display the Menu navigation at the top
static navigationOptions = {
title : 'Menu'
}
//onPress uses the navigate to pass the dishId to Dishsetail
//to display the dish detail of the selected dish
render() {
//const {navigate} = this.props.navigation ;
const renderMenuItem = ({item, index}) => {
return (
<Tile
key={index}
title={item.name}
caption={item.description}
featured
onPress={() => navigate('Dishdetail', { dishId: item.id })}
imageSrc={{ uri: baseUrl + item.image }}
/>
);
}
//extract the navigation comp passed to be used to pass
//dishId to Dishdetail
//const { navigate } = this.props.navigation ;
return (
<FlatList
data= {this.props.dishes.dishes}
renderItem={renderMenuItem}
keyExtractor={Item => Item.id.toString() }
/>
)
}
}
export default connect(mapStateToProps)(Menu);
DishdetailComponent.js
import React, { Component } from 'react' ;
import { View, Text, ScrollView, FlatList } from 'react-native' ;
import { Card, Icon } from 'react-native-elements' ;
//import { DISHES} from '../shared/dishes';
//import { COMMENTS } from '../shared/comments';
//1.import to connect to redux
import { connect } from 'react-redux';
import {baseUrl } from '../shared/baseUrl';
//2.leaders state from store
const mapStateToProps = state => {
return {
dishes: state.dishes,
comments: state.comments
}
}
//functional component: Display the selectedDish name, image and
//description using <Card> element
function RenderDish(props){
const dish = props.dish;
if (dish != null) {
return (
<Card
featuredTitle={dish.name}
image={{ uri: baseUrl + dish.image }}
>
<Text style={{margin: 10}}>
{dish.description}
</Text>
<Icon
raised
reverse
name={props.favorite ? 'heart' : 'heart-o'}
type='font-awesome'
color='#f50'
onPress={() => props.favorites ? console.log('Already favorite'): props.onPress() }
/>
</Card>
)
}
else {
return (<View></View>)
}
}
// display comments associted with dish
function RenderComments(props) {
// pull the content out from comments array
const comments = props.comments;
const renderCommentsItem = ({ item , index}) => {
return (
<View key={index} style={{ margin: 10}} >
<Text style={{fonSize: 14 }}>{item.comment}</Text>
<Text style={{fontSize: 12}}>{item.rating} Stars</Text>
<Text style={{ fontSize: 12}}>{'--' + item.author + ',' + item.date}</Text>
</View>
)
}
return (
<Card title="Comments">
<FlatList
data={comments}
renderItem={renderCommentsItem}
keyExtractor={item => item.id.toString()}
/>
</Card>
)
}
class Dishdetail extends Component {
constructor(props) {
super(props)
this.state = {
favorites: []
}
}
markFavourite(dishId) {
this.setState({favorites: this.state.favorites.concat(dishId)})
}
//setup the navigation for the current class [Dishdetail]
static navigationOptions = {
title : 'Dish Details'
}
render(){
// pass or extract the dish id through the navigation
const dishId = this.props.navigation.getParam('dishId', '');
return (
<ScrollView>
<RenderDish dish={this.props.dishes.dishes[+dishId]}
favorites={this.state.favorites.some(el => el === dishId)}
onPress={() => this.markFavourite(dishId)}/>
<RenderComments comments={this.props.comments.comments.filter((comment) => comment.dishId === dishId)} />
</ScrollView>
)
}
}
export default connect(mapStateToProps)(Dishdetail);

TopTabNavigator add custom icon

I'm following an tutorial and I got a little stuck.
I'm trying to add an custom icon in a react native tab navigator but I had not been lucky and hope some fellow member can guide me in the right direction.
import React from 'react';
import { createMaterialTopTabNavigator, Image} from 'react-navigation';
import FoldersList from '../screens/FoldersList';
const Routes = {
Home: {
screen: (props) => <FoldersList {...props} tabIndex={0}/>,
navigationOptions: {
title: 'Home'
}
},
MyNewTab: {
screen: (props) => <FoldersList {...props} tabIndex={1} createFolderTitle='Create new tab folder' />,
navigationOptions: {
title: 'MyNewTab'
}
},
MyThirdTab: {
screen: (props) => <FoldersList {...props} tabIndex={2} createFolderTitle='Create third tab folder'/>,
navigationOptions: {
tabBarIcon: ({ tintColor }) => {
return (<Image
style={{ width: 50, height: 50 }}
source={{ require: "../../images/AddFolder.png" }}/>);}
}
},
};
const routeConfig = {
swipeEnabled: false,
tabBarOptions: {
style: {
backgroundColor: '#013a65',
},
renderIndicator: () => null, // Indicatorline under tabbar
activeTintColor:'red',
inactiveTintColor:'#ffffff',
},
},
};
export default TabNavigator = createMaterialTopTabNavigator({
...Routes
}, routeConfig);
Hello here is a simple code:
UPDATE
class MyHomeScreen extends React.Component {
static navigationOptions = {
tabBarLabel: 'Home',
// Note: By default the icon is only shown on iOS. Search the showIcon
option below.
tabBarIcon: ({ tintColor }) => (
<Image
source={require('./chats-icon.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
};
render() {
return (
<Button
onPress={() => this.props.navigation.navigate('Notifications')}
title="Go to notifications"
/>
);
}
}
class MyNotificationsScreen extends React.Component {
static navigationOptions = {
tabBarLabel: 'Notifications',
tabBarIcon: ({ tintColor }) => (
<Image
source={require('./notif-icon.png')}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
};
render() {
return (
<Button
onPress={() => this.props.navigation.goBack()}
title="Go back home"
/>
);
}
}
const styles = StyleSheet.create({
icon: {
width: 26,
height: 26,
},
});
const MyApp = TabNavigator({
Home: {
screen: MyHomeScreen,
},
Notifications: {
screen: MyNotificationsScreen,
},
}, {
tabBarPosition: 'top',
animationEnabled: true,
tabBarOptions: {
activeTintColor: '#e91e63',
},
});
According to the docs, the showIcon property is setted to false on Android ( https://web.archive.org/web/20171015002750/https://reactnavigation.org/docs/navigators/tab#tabBarOptions-for-TabBarTop-default-tab-bar-on-Android ).
IF THE ABOVE CODE DO NOT WORKS FOLLOW THE BELLOW STEPS:
const MyApp = TabNavigator({
Displayed: {
screen: MyHomeScreen,
navigationOptions: {
title: 'Favorites',
tabBar: {
icon: ({tintColor}) => (<Image
source={require('./chats-icon.png')}
style={{width: 26, height: 26, tintColor: tintColor}}
/>)
},
},
},
...
or
class MyHomeScreen extends React.Component {
static navigationOptions = {
title: 'Foo Bar',
tabBar: {
icon: ({ tintColor }) => (
<Image
source={require('./chats-icon.png')}
style={{width: 26, height: 26, tintColor: tintColor}}
/>
),
}
};
...
I really hope that some code help you...
if you until do not work if the codes bellow, please see this other code:
UPDATE
//Package json
//change "react-navigation-material-bottom-tabs": "0.1.2"
import React, {Component} from 'react';
import {View,
Text,
StyleSheet,
//use SafeAreaView to move the images away from the top of the phone
SafeAreaView,
Image} from 'react-native';
import {createMaterialBottomTabNavigator} from 'react-navigation-material-bottom-tabs';
import {createMaterialTopTabNavigator} from 'react-navigation'
//imports the icons
import Icon from 'react-native-vector-icons/Ionicons'
export default class App extends Component{
render(){
return(
<SafeAreaView style = {{ flex: 1, backgroundColor: '#f2f2f2'}} >
<AppTabNavigator/>
</SafeAreaView>
)
}
}
//homescreen and the text that is displayed on that page
class HomeScreen extends Component {
render() {
return(
<View style = {styles.container}>
<Text>Welcome to my Navigator! </Text>
</View>
);
}
}
//MyPage and the text that is displayed on that page
class MyPage extends Component {
render() {
return(
<View style = {styles.container}>
<Text>My Page </Text>
</View>
);
}
}
//settings and the text that is displayed on that page
class SettingsScreen extends Component {
render() {
return(
<View style = {styles.container}>
<Text>Settings </Text>
</View>
);
}
}
//settings and the text that is displayed on that page
class ProfileScreen extends Component {
render() {
return(
<View style = {styles.container}>
<Text>Profile </Text>
</View>
);
}
}
//ceated a topTabNavigator then moved the buttons to the bottom
const AppTabNavigator = createMaterialTopTabNavigator({
Home: {
screen: HomeScreen,
navigationOptions: {
tabBarLabel: 'Home',
tabBarIcon: ({tintColor}) => (
<Icon name="ios-home" color = {tintColor} size = {24}/>
)
}
},
Settings: {
screen: SettingsScreen,
navigationOptions: {
tabBarLabel: 'Settings',
tabBarIcon: ({tintColor}) => (
<Icon name="ios-settings" color = {tintColor} size = {24}/>
)
}
},
Profile: {
screen: ProfileScreen,
navigationOptions: {
tabBarLabel: 'Profile',
tabBarIcon: ({tintColor}) => (
// <Icon name="ios-profile" color = {tintColor} size = {24}/>
<Image
source={require('./assets/snack-icon.png')}
style={{
marginLeft: 1,
marginTop: 1,
width: 25,
height: 25,
tintColor: '#FF3D00',
}}
/>
)
}
},
MyPage: {
screen: MyPage,
navigationOptions: {
tabBarLabel: 'Page',
tabBarIcon: ({tintColor}) => (
<Icon name = "ios-body" color = {tintColor} size = {24} />
)
}
}
},
{
//starts the program on Home Screen
initialRouteName: 'Home',
//orders the screens
//order: ['Settings', 'Home'],
//puts a color when that screen is activated in the tabs
//activeTintColor: 'white',
//Allows for icons(only) to appear on inactive tabs when you have more than 3 tabs
shifting: true,
tabBarPosition: 'top',
// swipeEnabled: true,
// animationEnabled: false,
tabBarOptions: {
activeTintColor: 'red',
inactiveTintColor: 'grey',
style: {
backgroundColor: 'pink',
borderTopWidth: 0.5,
borderTopColor: 'grey'
},
// indicatorStyle: {
// height: 0
// },
showIcon: true
}
})
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center'
}
});
the code to help you is this:
Profile: {
screen: ProfileScreen,
navigationOptions: {
tabBarLabel: 'Profile',
tabBarIcon: ({tintColor}) => (
// <Icon name="ios-profile" color = {tintColor} size = {24}/>
<Image
source={require('./assets/snack-icon.png')}
style={{
marginLeft: 1,
marginTop: 1,
width: 25,
height: 25,
tintColor: '#FF3D00',
}}
/>
)
}
},

Update username in navigation drawer when login with diffrent user in react native

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>
);
}

Deep Linking in Nested Navigators in react navigation

I am using react-navigation and as per the structure of my application, we have a tab navigator inside stack navigator, I am not been able to find any proper guide for implementing Deep-Linking.
https://v1.reactnavigation.org/docs/deep-linking.html. this doesn't give any reference for nested navigators.
You have to basically pass a path to every upper route untill you come to you nested route. This is indipendent of the type of navigator you use.
const HomeStack = createStackNavigator({
Article: {
screen: ArticleScreen,
path: 'article',
},
});
const SimpleApp = createAppContainer(createBottomTabNavigator({
Home: {
screen: HomeStack,
path: 'home',
},
}));
const prefix = Platform.OS == 'android' ? 'myapp://myapp/' : 'myapp://';
const MainApp = () => <SimpleApp uriPrefix={prefix} />;
In this case to route to an inner Navigator this is the route: myapp://home/article.
This example is using react-navigation#^3.0.0, but is easy to transfer to v1.
So, after the arrival of V3 of react navigation, things got extremely stable. Now i will present you a navigation structure with deep-linking in a Switch navigator -> drawerNavigator-> tabNavigator -> stack-> navigator. Please go step by step and understand the structure and keep referring to official documentation at everystep
With nested navigators people generally mean navigation structure which consists of drawer navigator, tab navigator and stackNavigator. In V3 we have SwitchNavigator too. So let's just get to the code,
//here we will have the basic React and react native imports which depends on what you want to render
import React, { Component } from "react";
import {
Platform,
StyleSheet,
Text,
View, Animated, Easing, Image,
Button,
TouchableOpacity, TextInput, SafeAreaView, FlatList, Vibration, ActivityIndicator, PermissionsAndroid, Linking
} from "react-native";
import { createSwitchNavigator, createAppContainer, createDrawerNavigator, createBottomTabNavigator, createStackNavigator } from "react-navigation";
export default class App extends Component<Props> {
constructor() {
super()
this.state = {
isLoading: true
}
}
render() {
return <AppContainer uriPrefix={prefix} />;
}
}
class WelcomeScreen extends Component {
state = {
fadeAnim: new Animated.Value(0.2), // Initial value for opacity: 0
}
componentDidMount() {
Animated.timing( // Animate over time
this.state.fadeAnim, // The animated value to drive
{
toValue: 1,
easing: Easing.back(), // Animate to opacity: 1 (opaque)
duration: 1000,
useNativeDriver: true // Make it take a while
}
).start(); // Starts the animation
}
render() {
let { fadeAnim } = this.state;
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center", backgroundColor: '#000' }}>
<Animated.View // Special animatable View
style={{ opacity: fadeAnim }}
>
<TouchableOpacity
onPress={() => this.props.navigation.navigate("Dashboard")}
style={{
backgroundColor: "orange",
alignItems: "center",
justifyContent: "center",
height: 30,
width: 100,
borderRadius: 10,
borderColor: "#ccc",
borderWidth: 2,
marginBottom: 10
}}
>
<Text>Login</Text>
</TouchableOpacity>
</Animated.View>
<Animated.View // Special animatable View
style={{ opacity: fadeAnim }}
>
<TouchableOpacity
onPress={() => alert("buttonPressed")}
style={{
backgroundColor: "orange",
alignItems: "center",
justifyContent: "center",
height: 30,
width: 100,
borderRadius: 10,
borderColor: "#ccc",
borderWidth: 2
}}
>
<Text> Sign Up</Text>
</TouchableOpacity>
</Animated.View>
</View>
);
}
}
class Feed extends Component {
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Button
onPress={() => this.props.navigation.navigate("DetailsScreen")}
title="Go to details"
/>
</View>
);
}
}
class Profile extends Component {
render() {
return (
<SafeAreaView style={{ flex: 1, }}>
//Somecode
</SafeAreaView>
);
}
}
class Settings extends Component {
render() {
return (
<View style={{ flex: 1 }}>
//Some code
</View>
);
}
}
const feedStack = createStackNavigator({
Feed: {
screen: Feed,
path: 'feed',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Feed",
headerLeft: (
<Icon
style={{ paddingLeft: 10 }}
name="md-menu"
size={30}
onPress={() => navigation.openDrawer()}
/>
)
};
}
},
DetailsScreen: {
screen: Detail,
path: 'details',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Details",
};
}
}
});
const profileStack = createStackNavigator({
Profile: {
screen: Profile,
path: 'profile',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Profile",
headerMode: 'Float',
headerLeft: (
<Icon
style={{ paddingLeft: 10 }}
name="md-menu"
size={30}
onPress={() => navigation.openDrawer()}
/>
)
};
}
},
DetailsScreen: {
screen: Detail,
path: 'details',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Details"
};
}
}
});
const settingStack = createStackNavigator({
Settings: {
screen: Settings,
path: 'settings',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Settings",
headerLeft: (
<Icon
style={{ paddingLeft: 10 }}
name="md-menu"
size={30}
onPress={() => navigation.openDrawer()}
/>
)
};
}
},
DetailsScreen: {
screen: Detail,
path: 'details',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Details"
};
},
}
});
const DashboardTabNavigator = createBottomTabNavigator(
{
feedStack: {
screen: feedStack,
path: 'feedStack',
navigationOptions: ({ navigation }) => {
let tabBarVisible = true;
if (navigation.state.index > 0) {
tabBarVisible = false;
}
return {
tabBarLabel: "Feed",
tabBarVisible,
//iconName :`ios-list${focused ? '' : '-outline'}`,
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-list" color={tintColor} size={25} />
)
};
}
},
profileStack: {
screen: profileStack,
path: 'profileStack',
navigationOptions: ({ navigation, focused }) => {
let tabBarVisible = true;
if (navigation.state.index > 0) {
tabBarVisible = false
}
return {
tabBarVisible,
tabBarLabel: "Profile",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-man" color={tintColor} size={25} />
)
};
// focused:true,
}
},
settingStack: {
screen: settingStack,
path: 'settingsStack',
navigationOptions: ({ navigation }) => {
let tabBarVisible = true;
if (navigation.state.index > 0) {
tabBarVisible = false;
}
return {
tabBarVisible,
tabBarLabel: "Settings",
tabBarIcon: ({ tintColor }) => (
<Icon name="ios-options" color={tintColor} size={25} />
)
}
}
},
},
{
navigationOptions: ({ navigation }) => {
const { routeName } = navigation.state.routes[navigation.state.index];
return {
// headerTitle: routeName,
header: null
};
},
tabBarOptions: {
//showLabel: true, // hide labels
activeTintColor: "orange", // active icon color
inactiveTintColor: "#586589" // inactive icon color
//activeBackgroundColor:'#32a1fe',
}
}
);
const DashboardStackNavigator = createStackNavigator(
{
DashboardTabNavigator: {
screen: DashboardTabNavigator,
path: 'dashboardtabs'
},
DetailsScreen: {
screen: Detail,
path: 'details',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Details"
};
}
}
},
{
defaultNavigationOptions: ({ navigation }) => {
return {
headerLeft: (
<Icon
style={{ paddingLeft: 10 }}
name="md-menu"
size={30}
onPress={() => navigation.openDrawer()}
/>
)
};
}
}
);
const AppDrawerNavigator = createDrawerNavigator({
Dashboard: {
screen: DashboardStackNavigator,
path: 'welcome'
},
DetailsScreen: {
screen: Detail,
path: 'friends',
navigationOptions: ({ navigation }) => {
return {
headerTitle: "Details",
};
}
}
});
//Switch navigator , will be first to load
const AppSwitchNavigator = createSwitchNavigator({
Welcome: {
screen: WelcomeScreen,
},
Dashboard: {
screen: AppDrawerNavigator,
path: 'welcome'
}
});
const prefix = 'myapp://';
const AppContainer = createAppContainer(AppSwitchNavigator);
For the process to setup React-navigation deep-linking please follow the official documentation
DetailsScreen was in my different folder and that will have class component of your choice
To launch the App the deep-link URL is myapp://welcome
To go to root page the deep-link URL is myapp://welcome/welcome
(this will reach at first page of first tab of tab navigator)
To go to any particular screen of tab navigator (suppose details
screen in profile tab) -
myapp://welcome/welcome/profileStack/details
const config = {
Tabs: {
screens: {
UserProfile: {
path: 'share//user_share/:userId',
parse: {
userId: (userId) => `${userId}`,
},
},
},
},
};
const linking = {
prefixes: ['recreative://'],
config,
};
if you have a screen in tab navigator you can do it like this via react-navigation v5

How To Reload View Tap on TabNavigator in React Native

I want to reload the tabNavigator when the user changse the tab each time. the lifecycle method of react native doesn't get called when user changes the tab. Then how can it be possible to reload tab in TabNavigator :
The below example have two Tabs : 1) Home 2)Events. Now I want to refresh the event Tab when user returns from the home tab.
EXPO LINK : Expo Tab Navigator
Code :
import React, {Component} from 'react';
import {View, StyleSheet, Image, FlatList, ScrollView, Dimensions } from 'react-native';
import { Button, List, ListItem, Card } from 'react-native-elements' // 0.15.0
//import { Constants } from 'expo';
import { TabNavigator, StackNavigator } from 'react-navigation'; // 1.0.0-beta.11
//image screen width and height defs
const windowWidth = Dimensions.get('window').width;
const windowHeight = Dimensions.get('window').height;
export default class App extends Component {
render() {
//const { navigate } = this.props.navigation;
return (
<TabsNav />
)
}
}
class MyHomeScreen extends Component {
render() {
return (
<View>
<Image
resizeMode="cover"
style={{ width: windowWidth * .85, height: windowHeight * 0.3}}
source={{uri: 'http://www.ajaxlibrary.ca/sites/default/files/media/logo.png?s358127d1501607090'}}
/>
<Button
onPress={() => this.props.navigation.navigate('Notifications')}
title="Go to notifications"
/>
</View>
);
}
}
class AplEvents extends Component {
static navigationOptions = {
tabBarLabel: 'Events List',
tabBarIcon: ({ tintColor }) => (
<Image
source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
};
constructor(props) {
super(props);
this.state = {
data: [],
error: null,
};
}
// when component mounts run the function fetch
componentDidMount() {
this.makeRemoteRequest();
}
makeRemoteRequest = () => {
const url = `http://www.ajaxlibrary.ca/?q=calendar-test`;
fetch(url)
.then((res) => res.json())
.then((res) => {
this.setState({
data: [...this.state.data, ...res.nodes],
error: res.error || null,
});
})
.catch(error => {
this.setState( error );
});
};
render() {
const { navigate } = this.props.navigation;
return (
<List containerStyle={{ marginTop: 0, borderTopWidth: 0, borderBottomWidth: 0 }}>
<FlatList
data={this.state.data}
renderItem={({ item }) => (
<ListItem
//squareAvatar
title={`${item.node.title}\n${item.node.Program_Location}`}
subtitle={item.node.Next_Session}
avatar={{ uri: item.node.Image }}
containerStyle={{ borderBottomWidth: 0 }}
// save params to pass to detailed events screen
onPress={() => navigate('Details', {title: `${item.node.title}`,
body: `${item.node.Body}`,
date: `${item.node.Date}`,
Next_Session: `${item.node.Next_Session}`,
Program_Location: `${item.node.Program_Location}`,
Nid: `${item.node.Nid}`,
Image: `${item.node.Image}`,
Run_Time: `${item.node.Run_Time}`})}
/>
)}
keyExtractor={item => item.node.Nid}
/>
</List>
);
}
}
class EventDetails extends Component {
static navigationOptions = {
title: 'EventDetails'
};
render() {
const { params } = this.props.navigation.state;
let pic = {
uri: `${params.Image}`
};
//const pic = { params.Image };
return (
<ScrollView>
<Card
title={params.title}
>
<Image
resizeMode="cover"
style={{ width: windowWidth * .85, height: windowHeight * 0.3}}
source={pic}
/>
<Button style={{marginTop: 10}}
icon={{name: 'date-range'}}
backgroundColor='#03A9F4'
fontFamily='Lato'
buttonStyle={{borderRadius: 0, marginLeft: 0, marginRight: 0, marginBottom: 0}}
title='Add to Calendar'
/>
<ListItem
title="Event Description"
subtitle={params.body}
hideChevron='true'
/>
<ListItem
title="Date"
subtitle={`${params.Next_Session}\n Run Time - ${params.Run_Time}`}
hideChevron='true'
/>
<ListItem
title="Location"
subtitle={params.Program_Location}
hideChevron='true'
/>
</Card>
</ScrollView>
);
}
}
const styles = StyleSheet.create({
icon: {
width: 26,
height: 26,
},
});
const EventStack = StackNavigator({
EventList: {
screen: AplEvents,
navigationOptions: {
title: "APL Event Listing",
}
},
Details: {
screen: EventDetails,
},
TabsNav: { screen: MyHomeScreen}
});
const TabsNav = TabNavigator({
Home: {
screen: MyHomeScreen,
navigationOptions: {
tabBarLabel: 'Home',
tabBarIcon: ({ tintColor }) => (
<Image
source={{uri: 'https://upload.wikimedia.org/wikipedia/de/thumb/9/9f/Twitter_bird_logo_2012.svg/154px-Twitter_bird_logo_2012.svg.png'}}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
},
},
EventList: {
screen: EventStack,
navigationOptions: {
tabBarLabel: 'Events',
tabBarIcon: ({ tintColor }) => (
<Image
source={{uri: 'https://upload.wikimedia.org/wikipedia/de/thumb/9/9f/Twitter_bird_logo_2012.svg/154px-Twitter_bird_logo_2012.svg.png'}}
style={[styles.icon, {tintColor: tintColor}]}
/>
),
},
},
}, {
tabBarOptions: {
activeTintColor: '#e91e63',
},
});
React Native Tab Navigation has an option prop as unmountOnBlur set it to true and it will reload the tab screens every time you click on tabs.
<Tab.Screen name={"Profile"} component={ProfileScreen} options={{unmountOnBlur: true}} />
Doc/Ref - RN Bottom tab Navigator docs
.
Update - There is a hook called as useIsFocused in '#react-navigation/native'.
Use this with useEffect to re-render the screen every time it is focused or used .
import { useIsFocused } from '#react-navigation/native';
const isFocused = useIsFocused();
useEffect(() => { yourApiCall(); }, [isFocused])
look at this link. My problem is solving thanks to this.
<Tabs.Navigator
initialRouteName="Home"
tabBar={(props) => (
<TabBar {...props} />
)}>
<Tabs.Screen
name="Home"
component={HomeView}
options={{ unmountOnBlur: true }}
listeners={({ navigation }) => ({
blur: () => navigation.setParams({ screen: undefined }),
})}
/>
</Tabs.Navigator>
https://github.com/react-navigation/react-navigation/issues/6915#issuecomment-692761324
There's many long discussion about this from react-native issue 314, 486, 1335, and finally we got a way to handle this, after Sep 27, 2017, react-navigation version v1.0.0-beta.13:
New Features
Accept a tabBarOnPress param (#1335) - #cooperka
So here we go,
Usage:
const MyTabs = TabNavigator({
...
}, {
tabBarComponent: TabBarBottom /* or TabBarTop */,
tabBarPosition: 'bottom' /* or 'top' */,
navigationOptions: ({ navigation }) => ({
tabBarOnPress: (scene, jumpToIndex) => {
console.log('onPress:', scene.route);
jumpToIndex(scene.index);
},
}),
});
I wasn't able to get this to work, and after checking the React Navigation documentation, found this, which seems to suggest that later versions (I'm using 1.0.0-beta.27) changed the method signature to a single object:
tabBarOnPress Callback to handle tap events; the argument is an object
containing:
the previousScene: { route, index } which is the scene we are leaving
the scene: { route, index } that was tapped
the jumpToIndex method
that can perform the navigation for you
https://reactnavigation.org/docs/en/tab-navigator.html#tabbaronpress
Given that, and the code from beausmith here, I put this together.
navigationOptions: ({ navigation }) => ({
tabBarOnPress: (args) => {
if (args.scene.focused) { // if tab currently focused tab
if (args.scene.route.index !== 0) { // if not on first screen of the StackNavigator in focused tab.
navigation.dispatch(NavigationActions.reset({
index: 0,
actions: [
NavigationActions.navigate({ routeName: args.scene.route.routes[0].routeName }) // go to first screen of the StackNavigator
]
}))
}
} else {
args.jumpToIndex(args.scene.index) // go to another tab (the default behavior)
}
}
})
Note that you'll need to import NavigationActions from react-navigation for this to work.
Hope this helps somebody :)