I have some issue when navigating from top Tabnavigator to other screens
so my app navigation is
My Orders Screen from Drawer => Top TabNavigatore (Accepted/Completed) => Order Details
In Route.js
I put every single navigation I want like Drawer - Auth navigation and so on, and I put a StackNavigator contain the Orders Screen like this:
const OrdersStack = createStackNavigator({
Orders: {
screen: Orders,
navigationOptions: ({ navigation }) => ({
headerLeft: (
// <TouchableOpacity onPress={() => navigation.dispatch(DrawerActions.toggleDrawer())}>
<TouchableOpacity
onPress={() => navigation.dispatch(DrawerActions.toggleDrawer())}
>
<Icon
name="ios-menu"
size={40}
style={{ margin: 10 }}
color="#2F98AE"
/>
</TouchableOpacity>
),
headerRight: <View />,
title: "My Orders",
headerTintColor: "#2F98AE",
headerStyle: {
borderBottomColor: "white"
},
headerTitleStyle: {
color: "#2F98AE",
// textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25
// justifyContent: "center"
}
})
}
});
In the Orders.js I put these:
import React, { Component } from "react";
import { createAppContainer, createStackNavigator } from "react-navigation";
import NavTabs from "../screens/NavTabs";
import NavOrderDetails from "../screens/NavOrderDetails";
// create a component
export default class Orders extends Component {
render() {
return <MyOrdersScreen />;
}
}
export const root = createStackNavigator({
NavTabs: NavTabs,
NavOrderDetails: NavOrderDetails
});
const MyOrdersScreen = createAppContainer(root);
As I mentioned in Orders.js it Contains Tabs and Order Details
In Tabs, I'm creating a createMaterialTopTabNavigator
import { createMaterialTopTabNavigator } from "react-navigation";
import AcceptedOrders from "../screens/AcceptedOrders";
import CompletedOrders from "../screens/CompletedOrders";
const MainTabs = createMaterialTopTabNavigator(
{
Accepted: { screen: AcceptedOrders },
Completed: { screen: CompletedOrders }
},
{
tabBarOptions: {
activeTintColor: "#fff",
inactiveTintColor: "#ddd",
tabStyle: {
justifyContent: "center"
},
indicatorStyle: {
backgroundColor: "#fcc11e"
},
style: {
backgroundColor: "#2F98AE"
}
}
}
);
export default MainTabs;
and another screen is OrderDeatils.js
import { createStackNavigator } from "react-navigation";
import OrderDetails from "../screens/OrderDetails";
import React, { Component } from "react";
import { View } from "react-native";
const OrderDetailsStack = createStackNavigator({
OrderDetails: {
screen: OrderDetails,
navigationOptions: () => ({
title: "Order Details",
headerRight: <View />,
headerTintColor: "#2F98AE",
headerStyle: {
borderBottomColor: "white"
},
headerTitleStyle: {
color: "#2F98AE",
flex: 1,
elevation: 0,
fontSize: 25
}
})
}
});
export default OrderDetailsStack;
Here are a screenShots it should explain what I mean
1- My Orders
2- Order Details
If i understand, you are concerned about the blank header that appears on top of the screen under your first header.
That one is created by createStackNavigator.
A the first Stack that creates the first Header named OrdersStack.
Inside that you have the root constant (probably, as there isn't the full code) that is creating the second header.
Inside root you are then defining your createMaterialTopTabNavigator with your two screens, that's showing the topBar with the label "accepted" and "completed".
To hide that white space you have to disable your root header doing:
export const root = createStackNavigator({
NavTabs: NavTabs,
NavOrderDetails: NavOrderDetails
},
{
defaultNavigationOptions:{
header:null
}
});
UPDATE.
You have two ways to fix this and still have a backButton:
1) You can either create a parent CustomHeader that, using react-navigation's withNavigation HOC, is aware about his childrens navigation state.
2) Dinamically hide the parent header when the second one is showing. You can accomplish this using this.props.navigation.dangerouslyGetParent().dangerouslyGetParent().setParams({showHeader:false})
then your OrdersStack would be:
const OrdersStack = createStackNavigator({
Orders: {
screen: Orders,
navigationOptions: ({ navigation }) => {
var defaultHeader={
headerLeft: (
<TouchableOpacity
onPress={() => navigation.dispatch(DrawerActions.toggleDrawer())}
>
<Icon
name="ios-menu"
size={40}
style={{ margin: 10 }}
color="#2F98AE"
/>
</TouchableOpacity>
),
headerRight: <View />,
title: "My Orders",
headerTintColor: "#2F98AE",
headerStyle: {
borderBottomColor: "white"
},
headerTitleStyle: {
color: "#2F98AE",
// textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25
// justifyContent: "center"
}
}
if (navigation.state.params)
return(navigation.state.params.showHeader?{defaultHeader}:null)
else return defaultHeader
}
}
});
Related
I am struggling a little bit. I have tried to create more components for my React native app but after I did it my ButtonSaving stoped redirecting to Dashboard for some reason. I was trying some ways to pass onRowPress to component but without luck. What do I do incorrectly here please?
Login button is working fine => redirecting to Dashboard
ButtonSaving not working at all => should redirect to Dashboard
AppNavigator.js
import { createStackNavigator } from 'react-navigation-stack'
import { createAppContainer } from 'react-navigation';
import Homepage from './components/Homepage/Homepage';
import Dashboard from './components/Dashboard/Dashboard';
const AppNavigator = createStackNavigator({
Homepage: Homepage,
Dashboard: { screen: Dashboard},
},
{
initialRouteName: 'Homepage',
defaultNavigationOptions: {
headerStyle: {
backgroundColor: 'white',
opacity: 70,
borderBottomColor: 'white',
borderColor: 'white'
},
headerTintColor: 'black',
headerTitleStyle: {
fontWeight: 'bold'
}
}
}
);
const Container = createAppContainer(AppNavigator);
export default Container;
Homepage.js
import React from 'react';
import { StyleSheet, Text, View, Button, Image } from 'react-native';
import {NavigationActions} from 'react-navigation';
// COMPONENTS
import ButtonSaving from './ButtonSaving/ButtonSaving';
class Homepage extends React.Component {
constructor(props) {
super(props);
this.state = {
isLoading: false
},
this.handleClick = this.handleClick.bind(this);
this.onRowPress = this.onRowPress.bind(this);
}
handleClick() {
const counterApp = this.state.counter;
this.setState({
counter: counterApp + 1,
dashboard: 'Dashboard'
})
}
onRowPress = ({ navigation }) => {
this.props.navigation.navigate(this.state.dashboard);
}
render() {
return(
<View style={styles.container}>
{/* LOGIN BUTTON */}
<View style={styles.buttonContainer}>
<View style={styles.buttonLogin}>
<Button title="log in"
color="white"
onPress={() => this.props.navigation.navigate('Dashboard')}/>
</View>
</View>
{/* LOGO CONTAINER */}
<View style={styles.logoContainer}>
<Image
style={{height: 147, width: 170}}
source= {require('./REACT_NATIVE/AwesomeProject/logo.png')}
></Image>
</View>
{/* EXPLAINATION OF WALT */}
<Text style={styles.textContainer}>Lorem ipsum lorem upsum></Text>
{/* Needs to be refactored to VIEW */}
<ButtonSaving onPress={() => this.onRowPress}/>
</View>)
}
ButtonSaving.js
import React from 'react';
import { StyleSheet, Text, View, Button, Image, TouchableOpacity } from 'react-native';
import { LinearGradient } from 'expo-linear-gradient';
class ButtonSaving extends React.Component {
constructor(props) {
super(props);
this.state = {
},
this.onRowPress = this.onRowPress.bind(this);
}
onRowPress = ({ navigation }) => {
this.props.navigation.navigate(this.state.dashboard);
}
render(){
return(
<View style={styleButton.container}>
<LinearGradient
colors={[
'#00b38f',
'#7dcf5a'
]}
style={styleButton.opacityContainer}>
<TouchableOpacity>
<Button
title="Start Saving"
color='white'
onPress={this.onRowPress}/>
</TouchableOpacity>
</LinearGradient>
</View>
)
}
}
const styleButton = StyleSheet.create({
container: {
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
width: '100%',
height: 50,
justifyContent: 'center',
marginTop: '39%'
},
opacityContainer: {
height: 48,
borderRadius: 25,
backgroundColor: 'darkgreen',
width: '70%',
justifyContent: 'center',
alignItems: 'center'
}
})
export default ButtonSaving;
You miss to put dashboard in your state in ButtonSaving.js
In Homepage.js when your are calling handleClick ?. Dunno how you got that working...
You say in the onRowPress this:
this.props.navigation.navigate(this.state.dashboard);
but I don't see anywhere that you set this.state.dashboard.
Probabbly you missed set it up.
It was simple refactor and this helped!
<ButtonSaving navigation ={this.props.navigation}/>
I will update solution for others later.
There is no point to save "dashboard" in the Homepage state or the ButtonSaving state.
In Homepage.js you don't need to pass onPress to ButtonSaving
...
<ButtonSaving navigation={this.props.navigation}/>
...
Next in ButtonSaving.js
onRowPress = () => {
this.props.navigation.navigate('Dashboard');
}
I have main Tabs "Categories" and I want when I click to any one of them it will just appeared his Details,
so I'm decleare a flag to every category and update it when clicked to display category details, BUT I think this is a wrong idea! and other issue when I click to first category it's appear his details, but when I clicked other Category from the tabs, the first category it's still around!
So how can I handle these issue?
Snack Here
Here's my Code
import React, { Component } from 'react';
import { Text, View, ScrollView,TouchableOpacity } from 'react-native';
export default class App extends Component {
state = {
open:true,
cat2:false,
cat3:false,
cat4:false,
}
render() {
return (
<View style={{flex: 1}} >
<ScrollView style={{flexGrow: 0.05, backgroundColor: '#347ed8', paddingTop: 50}} horizontal>
<TouchableOpacity onPress={()=>this.setState({open:!this.state.open})} style={{width: 100}}><Text style={{color:"#fff",fontSize:18}}>cat1 </Text></TouchableOpacity>
<TouchableOpacity
onPress={()=>this.setState({
cat2:!this.state.cat2
})}
style={{width: 100}}><Text style={{color:"#fff",fontSize:18}}>Cat2</Text></TouchableOpacity>
<TouchableOpacity style={{width: 100}}><Text style={{color:"#fff",fontSize:18}}>Cat3</Text></TouchableOpacity>
<TouchableOpacity style={{width: 100}}><Text style={{color:"#fff",fontSize:18}}>Cat4</Text></TouchableOpacity>
<TouchableOpacity style={{width: 100}}><Text style={{color:"#fff",fontSize:18}}>Cat5</Text></TouchableOpacity>
</ScrollView>
<View style={{flex: 0.95, backgroundColor: '#ddd'}}>
{this.state.open && <View>
<Text>Category Details One Here</Text>
</View>}
{this.state.cat2 && <View>
<Text>Category Details Two Here!</Text>
</View>}
{this.state.cat3 && <View>
<Text>Category Details Three Here!</Text>
</View>}
{this.state.cat4 && <View>
<Text>Category Details four Here!</Text>
</View>}
</View>
</View>
);
}
}
A simple solution to do what you want is to use a React-navigation module.
This problem should be that you have not set up touch events elsewhere, and the values shown by setting the conditions for touch events are different. However, this condition can mess up your code, which can be handled simply using the 'React-navigation' module.
You can use createMaterialTopTabNavigator
Example
import {
createStackNavigator,
createMaterialTopTabNavigator,//React navigation version 4 and before
createAppContainer,
} from 'react-navigation';
import { createMaterialTopTabNavigator } from 'react-navigation-tabs'; //React navigation version 4
//import Navigator in our project
import FirstPage from './pages/FirstPage';
import SecondPage from './pages/SecondPage';
//Making TabNavigator which will be called in App StackNavigator
//we can directly export the TabNavigator also but header will not be visible
//as header comes only when we put anything into StackNavigator and then export
const TabScreen = createMaterialTopTabNavigator(
{
Home: { screen: FirstPage },
Settings: { screen: SecondPage },
},
{
tabBarPosition: 'top',
swipeEnabled: true,
animationEnabled: true,
tabBarOptions: {
activeTintColor: '#FFFFFF',
inactiveTintColor: '#F8F8F8',
style: {
backgroundColor: '#633689',
},
labelStyle: {
textAlign: 'center',
},
indicatorStyle: {
borderBottomColor: '#87B56A',
borderBottomWidth: 2,
},
},
}
);
//making a StackNavigator to export as default
const App = createStackNavigator({
TabScreen: {
screen: TabScreen,
navigationOptions: {
headerStyle: {
backgroundColor: '#633689',
},
headerTintColor: '#FFFFFF',
title: 'TabExample',
},
},
});
I want to navigate from Order screen To Home Screen but he doesn't work very well, every screen in the route is work, But Home screen Nope, Just back me to the Map screen, And I want Home Screen Not Map !! I already tell them to navigate to Home.
Here is structure I'm Dowing
Home -> Map -> Order, then Order -> Home
and in the Home, I have side menu Drawer check under the code.
Route.js
import React, { Component } from 'react';
import {
View,
TouchableOpacity,
} from 'react-native';
//Import required react-navigation component
import {
createDrawerNavigator,
createStackNavigator,
createAppContainer,
createSwitchNavigator
} from 'react-navigation';
//Import all the screens for Drawer/ Sidebar
import Home from "../screens/Home";
import Splash from "../screens/Splash";
import SignUp from "../screens/SignUp";
import SignIn from "../screens/SignIn";
import ForgetPassword from "../screens/ForgetPassword";
import Order from "../screens/Order";
import MapApp from "../screens/MapApp";
import Profile from "../screens/Profile";
import Icon from 'react-native-vector-icons/Ionicons';
//Navigation Drawer Structure for all screen
class NavigationDrawerStructure extends Component {
//Structure for the navigatin Drawer
toggleDrawer = () => {
//Props to open/close the drawer
this.props.navigationProps.toggleDrawer();
};
render() {
return (
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity onPress={this.toggleDrawer.bind(this)}>
<Icon name="md-menu" size={30} color='#fff' style={{ marginLeft: 10 }} />
</TouchableOpacity>
</View>
);
}
}
// Stack Navigator for app
const AuthStackNavigator = createStackNavigator({
//All the screen from the Screen1 will be indexed here
SignUp: {
screen: SignUp,
navigationOptions: () => ({
// header: null
title: "Sign Up",
headerLeft: null,
headerTintColor: "#0496FF",
headerStyle: {
borderBottomColor: "white"
},
headerTitleStyle: {
color: "#0496FF",
textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25,
justifyContent: "center"
}
})
},
SignIn: {
screen: SignIn,
navigationOptions: {
title: "Sign In",
headerRight: <View />,
headerTintColor: "#0496FF",
headerStyle: {
borderBottomColor: "white"
},
headerTitleStyle: {
color: "#0496FF",
textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25,
justifyContent: "center"
}
}
},
ForgetPassword: {
screen: ForgetPassword,
navigationOptions: {
title: "Forget Password",
headerRight: <View />,
headerTintColor: "#0496FF",
headerStyle: {
borderBottomColor: "white"
},
headerTitleStyle: {
color: "#0496FF",
textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25,
justifyContent: "center"
}
}
},
});
//Stack Navigator for First Option of Navigation Drawer
const HomeDrawer = createStackNavigator({
Home: {
screen: Home,
navigationOptions: ({ navigation }) => ({
title: 'Home',
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerRight: <View />,
headerStyle: {
backgroundColor: '#258fdb',
shadowOpacity: 0,
elevation: 0,
marginBottom: 20
},
headerTintColor: '#fff',
headerTitleStyle: {
textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25,
justifyContent: "center"
}
}),
},
MapApp: {
screen: MapApp,
navigationOptions: {
title: "Map",
headerRight: <View />,
headerLeft: <View />,
headerTintColor: "#fff",
headerStyle: {
backgroundColor: "#258fdb",
borderBottomColor: "white",
},
headerTitleStyle: {
textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25,
justifyContent: "center"
}
}
}
});
//Stack Navigator for Second Option of Navigation Drawer
const OrderDrawer = createStackNavigator({
Order: {
screen: Order,
navigationOptions: ({ navigation }) => ({
title: 'Order',
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#258fdb',
},
headerTintColor: '#fff',
}),
},
});
const ProfileDrawer = createStackNavigator({
Profile: {
screen: Profile,
navigationOptions: ({ navigation }) => ({
title: 'Profile',
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#258fdb',
},
headerTintColor: '#fff',
}),
},
})
//Drawer Navigator for the Navigation Drawer / Sidebar
const DrawerNavigator = createDrawerNavigator({
Home: {
screen: HomeDrawer,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: () => (
<Icon name="ios-home" size={30} color='#0496FF' />
),
},
},
Order: {
screen: OrderDrawer,
navigationOptions: {
drawerLabel: 'Order',
drawerIcon: () => (
<Icon name="ios-list-box" size={30} color='#0496FF' />
),
},
},
Profile: {
screen: ProfileDrawer,
navigationOptions: {
drawerLabel: 'Profile',
drawerIcon: () => (
<Icon name="ios-contact" size={30} color='#0496FF' />
),
},
},
});
const Navigations = createSwitchNavigator({
Authloading: Splash,
Auth: AuthStackNavigator, // the Auth stack
App: DrawerNavigator, // the App stack
})
export default MyApp = createAppContainer(Navigations);
Order.js
import React, { Component } from 'react';
import styles from "../Style/styles";
import firebase from "react-native-firebase";
import ImagePicker from "react-native-image-picker";
import { View, Text, StyleSheet, TextInput, ScrollView, KeyboardAvoidingView, TouchableOpacity, Image } from 'react-native';
// create a component
class Order extends Component {
constructor(props) {
super(props);
this.state = {
userId: null,
nameOfProblem: '',
description: '',
imageOfPrblem: '',
timeDate: {},
providerId: this.props.navigation.dangerouslyGetParent().getParam('providerId'),
}
}
componentDidMount() {
const userId = firebase.auth().currentUser.uid;
this.setState({ userId });
}
handleOrder = () => {
const { nameOfProblem, description, userId, imageOfPrblem, providerId } = this.state;
const PushData = firebase.database().ref("request/" + providerId + "/" + userId + "/orders/");
const ref = firebase.storage().ref("users/" + userId + "/UserImageOrders/" + path);
let file = imageOfPrblem.uri;
const path = "img_" + imageOfPrblem.fileName;
if (file) {
return (
PushData.update({
nameOfProblem: nameOfProblem,
description: description,
// ...this.state.nameOfProblem,
// ...this.state.description,
imageOfPrblem: imageOfPrblem
}).then(() => {
ref.put(file).then(() => {
console.log("File uploaded..")
setTimeout(() => {
this.props.navigation.navigate("Home"); // not working and get me back to Map screen, but when i navigate to other screen it's work fine!
}, 3000);
});
})
)
}
else {
return (
PushData.push({
nameOfProblem: nameOfProblem,
description: description,
}).then(() => {
setTimeout(() => {
this.props.navigation.navigate("Home"); // Not work
}, 3000);
})
)
}
// else {
// }
}
handleImages = () => {
const options = {
title: "Select Images!",
storageOptions: {
skipBackup: true,
path: "images"
}
};
ImagePicker.showImagePicker(options, response => {
console.log("Response = ", response);
if (response.uri) {
this.setState({ imageOfPrblem: response });
}
if (response.didCancel) {
console.log("User cancelled image picker");
} else if (response.error) {
console.log("ImagePicker Error: ", response.error);
} else if (response.customButton) {
console.log("User tapped custom button: ", response.customButton);
alert(response.customButton);
}
});
};
render() {
const { nameOfProblem, description, imageOfPrblem, timeDate } = this.state;
const { getParam } = this.props.navigation.dangerouslyGetParent();
const providerId = getParam('providerId');
const providerName = getParam('providerName');
return (
<ScrollView scrollEnabled={true}>
<KeyboardAvoidingView behavior="padding" keyboardVerticalOffset={70}>
<View style={[styles.container, { marginTop: 20 }]}>
<Text>Send Order To: {JSON.stringify(providerName)}, ID:{JSON.stringify(providerId)}</Text>
<TextInput
style={styles.textInput}
placeholder="Name of Problem"
value={nameOfProblem}
onChangeText={(nameOfProblem) => this.setState({ nameOfProblem })}
returnKeyType="next"
returnKeyLabel="next"
/>
<TextInput
style={[styles.textInput, {
borderRadius: 5,
borderWidth: 1,
height: 120,
fontSize: 16,
padding: 10,
marginTop: 8
}]}
placeholder="Description"
multiline={true}
numberOfLines={12}
textAlignVertical="top"
value={description}
onChangeText={(description) => this.setState({ description })}
returnKeyType="next"
returnKeyLabel="next"
/>
<TouchableOpacity onPress={this.handleImages}>
<View
style={{
backgroundColor: "#DBDBDB",
borderRadius: 100,
alignSelf: "center",
margin: 10,
paddingBottom: 2,
width: 120,
height: 120
}}
>
<Text
style={{
position: "absolute",
zIndex: 1,
fontSize: 40,
top: 67,
color: "#1567d3",
left: 99
}}
>
+
</Text>
<Image
source={{ uri: imageOfPrblem.uri }}
style={[styles.uploadAvatar, { borderRadius: 100 }]}
resizeMode="cover"
/>
</View>
</TouchableOpacity>
<TouchableOpacity
style={[styles.button, { backgroundColor: "#1567d3" }]}
onPress={this.handleOrder}
>
<Text style={{ color: "#fff", fontSize: 18 }}>Send</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
</ScrollView>
);
}
}
// define your styles
//make this component available to the app
export default Order;
You have two routes with the name "Home", one in HomeDrawer and one in DrawerNavigator. Rename the one in DrawerNavigator and it should navigate to the correct "Home".
For example:
HomeDrawer: { // renamed this from Home to HomeDrawer
screen: HomeDrawer,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: () => (
<Icon name="ios-home" size={30} color='#0496FF' />
),
},
},
When exporting Home.js, export it like this (using withNavigation ).
import React, { Component } from 'react'
import { Text, View } from 'react-native'
import { withNavigation } from 'react-navigation';
class Home extends Component {
render() {
return (
<View>
<Text> Home </Text>
</View>
)
}
}
export default withNavigation(Home);
Hello Guys,
I have some issue with React navigation V3,
In my app, I have an Authentication step to Entering to Home Screen and it doesn't have a Drawer Navigation as a default, it will be Stack Navigator
Splash => Sign-up => Sign-in => Home
And in The Home Screen must Contain a Drawer Navigation And StackNavigation at the same time.
I'm Write one file named as a Route.js contain all of my Navigations,
But Now
createAppContainer just accept on arg like this I think.
export default MyApp = createAppContainer(DrawerNavigator);
and I want to use my other StackNavigator Not Contained in a Drawer, how to solve this problem?
Here is a Route.js
import React, { Component } from 'react';
//import react in our code.
import {
StyleSheet,
Platform,
View,
Text,
Image,
TouchableOpacity,
} from 'react-native';
//Import required react-navigation component
import {
createDrawerNavigator,
createStackNavigator,
createAppContainer
} from 'react-navigation';
//Import all the screens for Drawer/ Sidebar
import Splash from "../screens/Splash";
import Home from "../screens/Home";
import SignUp from "../screens/SignUp";
import SignIn from "../screens/SignIn";
import ForgetPassword from "../screens/ForgetPassword";
import Order from "../screens/Order";
import MapApp from "../screens/MapApp";
import Icon from 'react-native-vector-icons/Ionicons';
//Navigation Drawer Structure for all screen
class NavigationDrawerStructure extends Component {
//Structure for the navigatin Drawer
toggleDrawer = () => {
//Props to open/close the drawer
this.props.navigationProps.toggleDrawer();
};
render() {
return (
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity onPress={this.toggleDrawer.bind(this)}>
<Icon name="md-menu" size={30} color='#009' style={{ width: 25, height: 25, marginLeft: 5 }} />
</TouchableOpacity>
</View>
);
}
}
const Route = createStackNavigator({
//All the screen from the Screen1 will be indexed here
Splash: {
screen: Splash,
navigationOptions: {
header: null
},
},
SignUp: {
screen: SignUp,
navigationOptions: () => ({
// header: null
title: "Sign Up",
headerLeft: null,
headerTintColor: "#0496FF",
headerStyle: {
borderBottomColor: "white"
},
headerTitleStyle: {
color: "#0496FF",
textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25,
justifyContent: "center"
}
})
},
SignIn: {
screen: SignIn,
navigationOptions: {
title: "Sign In",
headerRight: <View />,
headerTintColor: "#0496FF",
headerStyle: {
borderBottomColor: "white"
},
headerTitleStyle: {
color: "#0496FF",
textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25,
justifyContent: "center"
}
}
},
ForgetPassword: {
screen: ForgetPassword,
navigationOptions: {
title: "Forget Password",
headerRight: <View />,
headerTintColor: "#0496FF",
headerStyle: {
borderBottomColor: "white"
},
headerTitleStyle: {
color: "#0496FF",
textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25,
justifyContent: "center"
}
}
},
MapApp: {
screen: MapApp,
navigationOptions: {
title: "Map",
headerRight: <View />,
headerLeft: <View />,
headerTintColor: "#0496FF",
headerStyle: {
backgroundColor: "#fafafa",
borderBottomColor: "white",
},
headerTitleStyle: {
color: "#0496FF",
textAlign: "center",
flex: 1,
elevation: 0,
fontSize: 25,
justifyContent: "center"
}
}
}
});
//Stack Navigator for First Option of Navigation Drawer
const FirstActivity_StackNavigator = createStackNavigator({
Home: {
screen: Home,
navigationOptions: ({ navigation }) => ({
title: 'Home',
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#FF9800',
shadowOpacity: 0,
elevation: 0,
},
headerTintColor: '#fff',
}),
},
});
//Stack Navigator for Second Option of Navigation Drawer
const Screen2_StackNavigator = createStackNavigator({
//All the screen from the Screen2 will be indexed here
Order: {
screen: Order,
navigationOptions: ({ navigation }) => ({
title: 'Order',
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#FF9800',
},
headerTintColor: '#fff',
}),
},
});
//Drawer Navigator for the Navigation Drawer / Sidebar
const DrawerNavigatorExample = createDrawerNavigator({
//Drawer Optons and indexing
Screen1: {
//Title
screen: FirstActivity_StackNavigator,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: () => (
<Icon name="ios-home" size={30} color='#009' />
),
},
},
Screen2: {
screen: Screen2_StackNavigator,
navigationOptions: {
drawerLabel: 'Order',
drawerIcon: () => (
<Icon name="ios-list-box" size={30} color='#009' />
),
},
},
});
export default MyApp = createAppContainer(DrawerNavigatorExample);
App.js
import React, { Component } from "react";
import MyApp from './src/navigations/Route'
export default class App extends Component {
render() {
return (
<MyApp />
)
}
}
Not sure if I understand your question so well, But what I suggest is to make each navigator in a different file like for example your StackNavigation in a file called "firstActivity_StackNavigator.js" and then you need to export the navigator as follow:
...
const FirstActivity_StackNavigator = createStackNavigator({
Home: {
screen: Home,
navigationOptions: ({ navigation }) => ({
title: 'Home',
headerLeft: <NavigationDrawerStructure navigationProps={navigation} />,
headerStyle: {
backgroundColor: '#FF9800',
shadowOpacity: 0,
elevation: 0,
},
headerTintColor: '#fff',
}),
},
});
export default FirstActivity_StackNavigator;
Then in your main navigator you just import whatever navigators you want
import FirstActivity_StackNavigator from "./firstActivity_StackNavigator.js"
import Screen2_StackNavigator from "./screen2_StackNavigator.js"
const DrawerNavigatorExample = createDrawerNavigator({
//Drawer Optons and indexing
Screen1: {
//Title
screen: FirstActivity_StackNavigator,
navigationOptions: {
drawerLabel: 'Home',
drawerIcon: () => (
<Icon name="ios-home" size={30} color='#009' />
),
},
},
Screen2: {
screen: Screen2_StackNavigator,
navigationOptions: {
drawerLabel: 'Order',
drawerIcon: () => (
<Icon name="ios-list-box" size={30} color='#009' />
),
},
},
});
...
Hopefully this answer your question
I'm trying to create a React Native app with some basic routing.
This is my code so far:
App.js:
import React from 'react'
import { StackNavigator } from 'react-navigation'
import MainScreen from './classes/MainScreen'
const AppNavigator = StackNavigator(
{
Index: {
screen: MainScreen,
},
},
{
initialRouteName: 'Index',
headerMode: 'none'
}
);
export default () => <AppNavigator />
MainScreen.js:
import React, { Component } from 'react'
import { StyleSheet, Text, View, Button, TouchableOpacity, Image } from 'react-native'
import HomeButton from './HomeButton'
export default class MainScreen extends Component {
static navigatorOptions = {
title: 'MyApp'
}
constructor(props) {
super(props)
}
render() {
return (
<View style={styles.container}>
<Image source={require('../img/logo.png')} style={{marginBottom: 20}} />
<HomeButton text='Try me out' classType='first' />
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
})
HomeButton.js:
import React, { Component } from 'react'
import { StyleSheet, Text, View, Button, TouchableOpacity } from 'react-native'
import { StackNavigator } from 'react-navigation'
export default class HomeButton extends Component {
constructor(props) {
super(props)
}
render() {
return (
<TouchableOpacity
onPress={() => navigate('Home')}
style={[baseStyle.buttons, styles[this.props.classType].style]}
>
<Text style={baseStyle.buttonsText}>{this.props.text.toUpperCase()}</Text>
</TouchableOpacity>
)
}
}
var Dimensions = require('Dimensions')
var windowWidth = Dimensions.get('window').width;
const baseStyle = StyleSheet.create({
buttons: {
backgroundColor: '#ccc',
borderRadius: 2,
width: windowWidth * 0.8,
height: 50,
shadowOffset: {width: 0, height: 2 },
shadowOpacity: 0.26,
shadowRadius: 5,
shadowColor: '#000000',
marginTop: 5,
marginBottom: 5
},
buttonsText: {
fontSize: 20,
lineHeight: 50,
textAlign: 'center',
color: '#fff'
}
})
const styles = {
first: StyleSheet.create({
style: { backgroundColor: '#4caf50' }
})
}
Everything works fine, but when pressing the button I get
Can't find variable: navigate
I've read that I have to declare it like this:
const { navigate } = this.props.navigation
So I edited HomeButton.js and added that line at the beginning of the render function:
render() {
const { navigate } = this.props.navigation
return (
<TouchableOpacity
onPress={() => navigate('Home')}
style={[baseStyle.buttons, styles[this.props.classType].style]}
>
<Text style={baseStyle.buttonsText}>{this.props.text.toUpperCase()}</Text>
</TouchableOpacity>
)
}
Now I get:
TypeError: undefined is not an object (evaluating 'this.props.navigation.navigate')
It seems that the navigation object is not coming into the properties, but I don't understand where should I get it from.
What am I missing here?
React-navigation pass navigation prop to the screen components defined in the stack navigator.
So in your case, MainScreen can access this.props.navigation but HomeButton can't.
It should work if you pass navigation prop from MainScreen to HomeButton :
<HomeButton text='Try me out' classType='first' navigation={this.props.navigation}/>
Edit: You have to define the Homescreen in your stack navigator in order to navigate to it, your onPress={() => navigate('Home')} won't work until then.