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

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

Related

React Native : Navigation issue with Navigation service ,not able to navigate on press

I have been following guide at https://reactnavigation.org/docs/3.x/navigating-without-navigation-prop/. However, when I create the Navigation service as per given code snippet and attempt to set the toplevel navigator in my navigator component, It is not navigating to desire screen.
I want to navigate to the brandscreen.js when clicking on brand-logo from homescreen (want tp implement Shop by Brand) but not able to navigate.
App.js
import React, { Component } from 'react';
import { View, Text, StyleSheet,Image} from 'react-native';
import { DrawerItems,
createStackNavigator,
createDrawerNavigator,
createAppContainer,
createSwitchNavigator,
createBottomTabNavigator} from 'react-navigation'
import HomeScreen from './app/screen/HomeScreen';
import ProfileScreen from './app/screen/ProfileScreen';
import Orders from './app/screen/Orders';
import Notification from './app/screen/Notification';
import Logout from './app/screen/Logout';
import EditProfile from './app/screen/EditProfile'
import {Box} from 'react-native-design-utility'
import Address from './app/screen/Address'
import { Container,Header,Content, Body, Icon,Button} from 'native-base';
import BrandScreen from './app/screen/BrandScreen';
import NavigationService from './app/services/NavigationService'
const profileheader={
headerStyle:{
backgroundColor: '#3a455c',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}
class WelcomeScreen extends Component {
render() {
return (
<Box f={1} center>
<Button block light style={styles.btn} onPress={()=>this.props.navigation.navigate('Dashboard')}>
<Text style={{fontSize:16,color:'white',fontWeight:'bold'}}>Login</Text>
</Button>
<Button block light style={styles.btn} onPress={()=>this.props.navigation.navigate('Welcome')}>
<Text style={{fontSize:16,color:'white',fontWeight:'bold'}}>Sign Up</Text>
</Button>
</Box>
);
}
}
const ProfileStack=createStackNavigator({
Profile:{
screen:ProfileScreen,
navigationOptions:({navigation})=>{
return {
headerLeft:<Icon name="md-menu" style={{color:'white',marginLeft:10}} onPress={()=>navigation.toggleDrawer()}/>,
headerStyle:{
backgroundColor: '#3a455c',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}
}
},
EditProfile:{
screen:EditProfile,
navigationOptions:{...profileheader},
}
})
const ProfiletTabNavigator=createBottomTabNavigator({
Profile:{
screen:ProfileStack,
navigationOptions: {
tabBarLabel: 'Profile',
tabBarIcon: () =><Icon name="md-person" size={25} style={{fontSize: 20,paddingTop:5}}/>
}
},
Address:{
screen:Address,
navigationOptions: {
tabBarLabel: 'Saved Address',
tabBarIcon: () =><Icon name="md-bookmark" size={25} style={{fontSize: 20,paddingTop:5}}/>
}
},
},{
navigationOptions:({navigation})=>{
const {routeName}=navigation.state.routes[navigation.state.index]
return {
headerTitle: routeName,
header:null,
headerStyle: {
backgroundColor: '#3a455c',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
},
}
}
})
const ProfileStackNavigator=createStackNavigator({
ProfiletTabNavigator:{
screen:ProfiletTabNavigator,
}
},{
defaultNavigationOptions:({navigation})=>{
return {
headerLeft:<Icon name="md-menu" style={{color:'white',marginLeft:10}} onPress={()=>navigation.toggleDrawer()}/>
}
}
});
const CustomDrawerContentComponent=(props)=>(
<Container>
<Header style={{height:130,backgroundColor:'#3a455c',marginTop:0}}>
<Body>
<Image name='person' style={styles.dImage}
source={require('./app/img/profile-image.jpg')}/>
</Body>
</Header>
<Content>
<DrawerItems {...props}/>
</Content>
</Container>
)
const HomeStack=createStackNavigator({
Home:{
screen:HomeScreen,
navigationOptions: {
header:null,
tabBarLabel: 'Home',
tabBarIcon: () => <Icon name="md-home" size={25} style={{fontSize: 20,paddingTop:5}}/>
},
Brand:BrandScreen
}
})
const AppDrawerNavigator=createDrawerNavigator ({
Home:{
screen:HomeStack,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: () =><Icon name="md-home" size={25} style={{fontSize: 20,paddingTop:5}}/>
}
},
Profile:{
screen:ProfileStackNavigator,
navigationOptions: {
drawerLabel: 'My Account',
drawerIcon: () =><Icon name="md-person" size={25} style={{fontSize: 20,paddingTop:5}}/>
}
},
Orders:Orders,
Notification:Notification,
Logout:Logout,
},{
initialRouteName:'Home',
contentComponent:CustomDrawerContentComponent,
})
const AppSwitchNavigator=createSwitchNavigator({
Welcome:WelcomeScreen,
Dashboard:AppDrawerNavigator,
})
const AppNavigator=createAppContainer(AppSwitchNavigator);
export default class App extends Component {
render() {
return (
<AppNavigator ref={r => NavigationService.setTopLevelNavigator(r)} />
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#2c3e50',
},
dImage:{
height:100,
width:100,
borderRadius:50,
},
btn:{
padding:10,
margin:10,
backgroundColor:'#273746',
borderRadius:4
}
});
NavigationService.js
let _navigator;
function setTopLevelNavigator( navigatorRef ){
_navigator = navigatorRef;
}
function navigate( routeName, params ){
_navigator.dispatch(
NavigationActions.navigate({
routeName,
params
})
);
}
export default {
navigate,
setTopLevelNavigator,
};
BrandCard.js
//import liraries
import React, { Component } from 'react';
import {Image,TouchableOpacity,StyleSheet} from 'react-native'
import {Box,Text} from 'react-native-design-utility'
import NavigationService from '../services/NavigationService';
class BrandCard extends Component {
state={};
handlepress =()=>{
NavigationService.navigate('Brand',{ name: this.props.title});
};
render() {
const {title,image}=this.props;
return(
<TouchableOpacity onPress={this.handlepress} style={{flex:1}}>
<Box center f={1}>
<Box>
<Image source={image} style={{height:100,weight:100,resizeMode:'contain'}}
/>
</Box>
</Box>
</TouchableOpacity>
)
}
}
export default BrandCard;
The only thing you are doing wrong is you are using a route name "brand" which is not declared in your routes.
NavigationService.navigate('Brand',{ name: this.props.title});
Here replace "Brand" with your correct routename.
Hope this helps!

Header is not showing in react-navigation-drawer React-Native

I am implementing react-navigation-drawer from React Navigation Library. But facing problem related to header. The header bar is not showing in any of the screens.
This is my App.js
import React from "react";
import { StyleSheet, ScrollView, View } from "react-native";
//import DrawerNavigator from "./navigation/DrawerNavigator";
import { Platform, Dimensions } from "react-native";
import { createAppContainer } from "react-navigation";
import { createDrawerNavigator } from "react-navigation-drawer";
import Home from "./components/home";
import Contact from "./components/contact";
const WIDTH = Dimensions.get("window").width;
const RouteConfigs = {
Home: {
screen: Home
},
Contact: {
screen: Contact
}
};
const DrawerNavigatorConfig = {
drawerWidth: WIDTH * 0.75,
drawerType: "both",
initialRouteName: "Home"
};
const DrawerNavigator = createDrawerNavigator(
RouteConfigs,
DrawerNavigatorConfig
);
const MyApp = createAppContainer(DrawerNavigator);
export default class App extends React.Component {
render() {
return <MyApp />;
}
}
And this is my home screen
import React, { Component } from "react";
import { View, Image, Text, StyleSheet, ScrollView } from "react-native";
import { FontAwesomeIcon } from "#fortawesome/react-native-fontawesome";
import { faTruck, faHome } from "#fortawesome/free-solid-svg-icons";
class Home extends Component {
static navigationOptions = {
headerTitle: "Home",
drawerIcon: ({ tintColor }) => <FontAwesomeIcon size={25} icon={faHome} />
};
render() {
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Home Screen</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#F5F5F5",
flexDirection: "column"
},
icon: {
width: 24,
height: 24
}
});
export default Home;
Can anyone help me. Thanks in advance!!!
#hongdeveloper this is a simple example solution for react navigation 5:
function Root() {
return (
<Stack.Navigator>
<Stack.Screen options={{title: "Profile"}} name="Profile" component={Profile} />
<Stack.Screen options={{title: "Settings"}} name="Settings" component={Settings} />
</Stack.Navigator>
);
}
function App() {
return (
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen name="Home" component={Home} />
<Drawer.Screen name="Root" component={Root} />
</Drawer.Navigator>
</NavigationContainer>
);
}
You can find about the navigation to a screen in a nested navigator in docs and you can try this example on Snack
The drawer navigator does not contain headers. Stack navigators must be configured to display headers.
const DrawerNavigator = createDrawerNavigator(
RouteConfigs,
DrawerNavigatorConfig
);
const Root = createStackNavigator({
Main: { screen : DrawerNavigator}
},
{
defaultNavigationOptions : ({ navigation }) => ({
title: "Screen"
})
})
const Stacks = createAppContainer(Root)
export default Stacks;
Since December 2020 you can now use the headerShown: true setting in screenOptions of your Drawer.Navigator to show the header in React Navigation 5.
See more about this issue here: https://github.com/react-navigation/react-navigation/issues/1632
See the commit and comments about the new feature in React Navigation 5 here
https://github.com/react-navigation/react-navigation/commit/dbe961ba5bb243e8da4d889c3c7dd6ed1de287c4
Late reply, But I did it with the below code.
I created separate stack navigators for each screen and after that added all the stack navigators in the drawer navigator.
The good thing is it is fully customized.
Please see my code below.
const WIDTH = Dimensions.get('window').width;
const HomeNavigator = createStackNavigator(
{
Home: Home
},
{
defaultNavigationOptions: ({ navigation }) => {
return {
headerStyle: {
backgroundColor: '#1e89f4'
},
headerTitle: 'Knowledge Woledge',
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
textAlign: 'center',
flex: 1
},
headerLeft: (
<View style={{ paddingLeft: 13 }}>
<FontAwesomeIcon
size={25}
color='#fff'
icon={faBars}
onPress={() => navigation.openDrawer()}
/>
</View>
),
headerRight: <View />
};
}
}
);
const DetailNavigator = createStackNavigator(
{
PostDetail: PostDetail
},
{
defaultNavigationOptions: ({ navigation }) => {
return {
headerStyle: {
backgroundColor: '#1e89f4'
},
headerTitle: () => {
return (
<Text
style={{
color: '#fff',
fontWeight: 'bold',
textAlign: 'center',
flex: 1,
fontSize: 20
}}
>
{navigation.getParam('headerTitle')}
</Text>
);
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold',
textAlign: 'center',
flex: 1
},
headerLeft: (
<View style={{ paddingLeft: 13 }}>
<FontAwesomeIcon
size={25}
color='#fff'
icon={faArrowLeft}
onPress={() => navigation.goBack(null)}
/>
</View>
),
headerRight: <View />
};
}
}
);
Assigned this in a const
const RouteConfigs = {
Home: {
screen: HomeNavigator,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: ({ tintColor }) => (
<FontAwesomeIcon size={20} color={tintColor} icon={faHome} />
)
}
},
Detail: {
screen: DetailNavigator,
navigationOptions: {
drawerLabel: () => {
return null;
}
}
}
};
And finally, create a drawer navigator with this.
const DrawerNavigatorConfig = {
drawerWidth: WIDTH * 0.75,
drawerType: 'both',
initialRouteName: 'Home'
};
const DrawerNavigator = createDrawerNavigator(
RouteConfigs,
DrawerNavigatorConfig
);
const Stacks = createAppContainer(DrawerNavigator);
export default Stacks;

Header is not visible in 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...
}
}

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

React-Navigation hide tabBar in StackNavigator inside a TabRouter

Having problem hiding the tabBar once we are inside StackNavigator which is inside TabRouter.
im using the navigatorOption, but it does not seem to be doing anything.
navigationOptions: {tabBarVisible: false}
can access expo.io from https://snack.expo.io/Sk4fQHAfZ
import React from 'react';
import {
Button,
Platform,
ScrollView,
StyleSheet,
Text,
TouchableOpacity,
View,
} from 'react-native';
import {
createNavigator,
createNavigationContainer,
TabRouter,
addNavigationHelpers,
StackNavigator,
} from 'react-navigation';
const MyNavScreen = ({ navigation, banner }) => (
<ScrollView>
<Text>{banner}</Text>
<Button
onPress={() => {
navigation.goBack(null);
}}
title="Go back"
/>
</ScrollView>
);
const NestedMyNavScreen = ({ navigation, banner }) => (
<ScrollView>
<Text>{banner}</Text>
<Button
onPress={() => navigation.navigate('Profile', { name: 'Jane' })}
title="Go to a profile screen"
/>
<Button
onPress={() => navigation.navigate('Photos', { name: 'Jane' })}
title="Go to a photos screen"
/>
</ScrollView>
);
const MyNotificationsScreen = ({ navigation }) => (
<MyNavScreen banner="Notifications Screen" navigation={navigation} />
);
const MySettingsScreen = ({ navigation }) => (
<MyNavScreen banner="Settings Screen" navigation={navigation} />
);
const MyPhotosScreen = ({ navigation }) => {
let params = navigation.state.routes[navigation.state.index].params;
// let params = navigation.state.params;
return <MyNavScreen
banner={`${params.name}'s Photos`}
navigation={navigation}
/>
};
MyPhotosScreen.navigationOptions = {
title: 'Photos',
};
const MyProfileScreen = ({ navigation }) => {
let params = navigation.state.routes[navigation.state.index].params;
// let params = navigation.state.params;
return <MyNavScreen
banner={`${params.mode === 'edit' ? 'Now Editing ' : ''}${params.name}'s Profile`}
navigation={navigation}
/>
};
const CustomTabBar = ({ navigation }) => {
const { routes } = navigation.state;
return (
<View style={styles.tabContainer}>
{routes.map(route => (
<TouchableOpacity
onPress={() => navigation.navigate(route.routeName)}
style={styles.tab}
key={route.routeName}
>
<Text>{route.routeName}</Text>
</TouchableOpacity>
))}
</View>
);
};
const SimpleStack = StackNavigator({
NestedHome: {
screen: NestedMyNavScreen
},
Profile: {
path: 'people/:name',
screen: MyProfileScreen,
navigationOptions: {tabBarVisible: false}
},
Photos: {
path: 'photos/:name',
screen: MyPhotosScreen,
},
});
const CustomTabView = ({ router, navigation }) => {
const { routes, index } = navigation.state;
const ActiveScreen = router.getComponentForState(navigation.state);
return (
<View style={styles.container}>
<ActiveScreen
navigation={addNavigationHelpers({
...navigation,
state: routes[index],
})}
/>
<CustomTabBar navigation={navigation} />
</View>
);
};
const CustomTabRouter = TabRouter(
{
Home: {
screen: SimpleStack,
path: '',
},
Notifications: {
screen: MyNotificationsScreen,
path: 'notifications',
},
Settings: {
screen: MySettingsScreen,
path: 'settings',
},
},
{
// Change this to start on a different tab
initialRouteName: 'Home',
}
);
const CustomTabs = createNavigationContainer(
createNavigator(CustomTabRouter)(CustomTabView)
);
const styles = StyleSheet.create({
container: {
marginTop: Platform.OS === 'ios' ? 20 : 0,
flexDirection: 'column',
justifyContent: 'space-between',
flex: 1
},
tabContainer: {
flexDirection: 'row',
height: 48,
},
tab: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
margin: 4,
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 4,
},
});
export default CustomTabs;
Seems like its not working when your using your custom tabRouter.
I got it to work removing it : https://snack.expo.io/H1NmvXE5b
(Also in your expo link you've wrongly used {tabBar : {visible:false}}
You can try and style your tab bar buttons either in each screen in the navigationOptions
OR
you could do it the way its done here:
(Just for example sake from the native-base docs:)
export default MainScreenNavigator = TabNavigator(
{
LucyChat: { screen: LucyChat },
JadeChat: { screen: JadeChat },
NineChat: { screen: NineChat }
},
{
tabBarPosition: "bottom",
tabBarComponent: props => {
return (
<Footer>
<FooterTab>
<Button
vertical
active={props.navigationState.index === 0}
onPress={() => props.navigation.navigate("LucyChat")}>
<Icon name="bowtie" />
<Text>Lucy</Text>
</Button>
<Button
vertical
active={props.navigationState.index === 1}
onPress={() => props.navigation.navigate("JadeChat")}>
<Icon name="briefcase" />
<Text>Nine</Text>
</Button>
<Button
vertical
active={props.navigationState.index === 2}
onPress={() => props.navigation.navigate("NineChat")}>
<Icon name="headset" />
<Text>Jade</Text>
</Button>
</FooterTab>
</Footer>
);
}
}
));
The problem is that you can only set navigation options for the navigator that renders a given screen. The screen that you want to hide the tab bar on is rendered by a stacknavigator, which does not have a tabBarVisible navigation option.
This link to the docs explains in more detail:
https://reactnavigation.org/docs/en/navigation-options-resolution.html#a-stack-contains-a-tab-navigator-and-you-want-to-set-the-title-on-the-stack-header
The solution is to set the navigation options in your stackNavigator, which is rendered by the tabNavigator. You can use a function to vary the navigation option per screen. Below is an example from the docs:
https://reactnavigation.org/docs/en/navigation-options-resolution.html#a-stack-contains-a-tab-navigator-and-you-want-to-set-the-title-on-the-stack-header
Here's another simple example:
const HomeStack = createStackNavigator(
{
Home: HomeScreen,
Settings: SettingsScreen
},
{
initialRouteName: "Home",
}
);
HomeStack.navigationOptions = ({ navigation }) => {
// get the name of the route
const { routeName } = navigation.state.routes[navigation.state.index];
if (routeName === 'Settings'){
tabBarVisible = false;
}
else{
tabBarVisible = true;
}
return {
tabBarVisible, // this now varies based on screen
tabBarLabel: "Search", // this is the same for all screens
};
};
export default createBottomTabNavigator(
{
HomeStack,
})