When I add the <Menu /> component to my header as below:
let SearchPage = (props) => {
const menu = (
<Container>
<Header style={styles.header}>
<Left>
<Button >
<Menu />
</Button>
</Left>
<Body>
I get the error
Maximum call stack size exceeded
and of course if I comment out the <Menu /> line in my SearchPage, there is no error.
The menu is a react-native-off-canvas-menu
My menu component:
components/menu/Menu.js
import React from 'react'
import { View, Icon } from 'react-native'
import { connect } from 'react-redux'
import { togglePageMenu } from './menu.action'
import { OffCanvas3D } from 'react-native-off-canvas-menu'
//import AddPage from '../add-page/AddPage'
import SearchPage from '../search-page/SearchPage'
const mapStateToProps = (state) => ({
isOpen: state.get('menu').isOpen
})
const mapDispatchToProps = (dispatch) => ({
togglePageMenu: () => {
dispatch(togglePageMenu())
}
})
let Menu = (props) => (
<View style={{ flex: 1 }}>
<OffCanvas3D
active={props.isOpen}
onMenuPress={props.togglePageMenu}
backgroundColor={'#222222'}
menuTextStyles={{ color: 'white' }}
handleBackPress={true}
menuItems={[
{
title: 'Search Products',
icon: <Icon name="camera" size={35} color='#ffffff' />,
renderScene: <SearchPage />
}
]} />
</View>
)
Menu.propTypes = {
togglePageMenu: React.PropTypes.func.isRequired,
isOpen: React.PropTypes.bool.isRequired
}
Menu = connect(
mapStateToProps,
mapDispatchToProps
)(Menu)
export default Menu
What could be causing the error?
Here is my component that uses the menu (probably not relevant):
components/search-page/SearchPage.js
import { ScrollView, StyleSheet, View } from 'react-native'
import {
Container,
Button,
Text,
Header,
Body,
Right,
Left,
Title,
Icon
} from 'native-base'
import React from 'react'
import Keywords from '../keywords/Keywords'
import Categories from '../categories/Categories'
import Location from '../location/Location'
import Menu from '../menu/Menu'
import DistanceSlider from '../distanceSlider/DistanceSlider'
import Map from '../map/Map'
import Drawer from 'react-native-drawer'
import { connect } from 'react-redux'
import { toggleMenu } from './searchPage.action'
import { styles, wideButtonColor } from '../../style'
import searchPageStyle from './style'
import { selectIsSearchFormValid } from './isSearchFormValid.selector'
const mapStateToProps = (state) => ({
isMenuOpen: state.get('searchPage').get('isMenuOpen'),
isSearchFormValid: selectIsSearchFormValid(state)
})
const mapDispatchToProps = (dispatch) => ({
toggleMenu: () => {
dispatch(toggleMenu())
}
})
let SearchPage = (props) => {
const menu = (
<Container>
<Header style={styles.header}>
<Left>
<Button >
<Menu />
</Button>
</Left>
<Body>
<Title style={styles.title}>Search Products</Title>
</Body>
<Right>
</Right>
</Header>
<Container style={styles.container}>
<ScrollView keyboardShouldPersistTaps={true}>
<Categories />
<View style={searchPageStyle.locationContainer}>
<Location />
</View>
<DistanceSlider />
<Keywords />
<Button
block
style={{
...searchPageStyle.goButton,
backgroundColor: wideButtonColor(!props.isSearchFormValid)
}}
disabled={!props.isSearchFormValid}
onPress={props.toggleMenu}>
<Text>GO</Text>
</Button>
</ScrollView>
</Container>
</Container>
)
return (
<Drawer open={props.isMenuOpen} content={menu}>
<Container style={mapStyles.container}>
<Map />
</Container>
</Drawer>
)
}
SearchPage.propTypes = {
toggleMenu: React.PropTypes.func.isRequired,
isMenuOpen: React.PropTypes.bool.isRequired,
isSearchFormValid: React.PropTypes.bool.isRequired
}
SearchPage = connect(
mapStateToProps,
mapDispatchToProps
)(SearchPage)
export default SearchPage
const mapStyles = StyleSheet.create({
container: {
...StyleSheet.absoluteFillObject,
height: 400,
width: 400,
justifyContent: 'flex-end',
alignItems: 'center',
}
})
It's because you are rendering another <SearchPage /> within your menu: renderScene: <SearchPage />. This creates a circular dependency where a SearchPage is creating a Menu and the Menu is creating a SearchPage... etc. Until, as you saw, you run out of memory.
Related
Would anyone be able to give me help regarding React Navigation with Expo? The issue is with the drawer component where the 'Hamburger' icon isn't opening or closing the component when a user presses the icon. However, it does open/close on a default swipe gesture from React Navigation. Please see below for my code:
Router:
import React from 'react';
import { NavigationContainer, DrawerActions } from '#react-navigation/native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { IconButton } from 'react-native-paper'
import i18n from '../i18n/i18n';
//Theme
import Theme from '../theme/theme'
//Components
import Menu from '../components/Menu'
//Import Interfaces
import { RootDrawerParamList } from '../utils/typescript/type.d';
import { IProps } from '../utils/typescript/props.d';
//Import Screens
import Screen1 from '../screens/Screen1';
import Screen2 from '../screens/Screen2';
import SettingsScreen from '../screens/Settings';
const Drawer = createDrawerNavigator<RootDrawerParamList>();
export default class Router extends React.Component<IProps, any> {
constructor(props: IProps) {
super(props);
}
render() {
return (
<NavigationContainer>
<Drawer.Navigator
initialRouteName='Screen1'
drawerContent={(props: any) => <Menu {...props} />}
screenOptions={({
swipeEnabled: true
})}>
<Drawer.Screen
name="Screen1"
component={Screen1}
initialParams={{ i18n: i18n, Theme: Theme }}
options={({route, navigation} : any) => ({
headerRight: () => (<IconButton icon="cog" size={24} color={Theme.colors.text} onPress={() => navigation.navigate('Settings')} />),
route: {route},
navigation: {navigation}
})}
/>
<Drawer.Screen
name="Settings"
component={SettingsScreen}
initialParams={{ i18n: i18n, Theme: Theme }}
options={({route, navigation} : any) => ({
headerTitle: i18n.t('settings', 'Settings'),
headerLeft: () => (<IconButton icon="arrow-left" color={Theme.colors.text} size={24} onPress={() => navigation.goBack()} />),
route: {route},
navigation: {navigation}
})}
/>
<Drawer.Screen
name="Screen2"
component={Screen2}
initialParams={{ i18n: i18n, Theme: Theme }}
options={({route, navigation} : any) => ({
route: {route},
navigation: {navigation}
})}
/>
</Drawer.Navigator>
</NavigationContainer>
);
}
}
Menu
import React from 'react';
import { FlatList, StyleSheet, View } from 'react-native';
import { List, Title } from 'react-native-paper';
import { getDefaultHeaderHeight } from '#react-navigation/elements';
import { DrawerItem } from '#react-navigation/drawer';
import { useSafeAreaFrame, useSafeAreaInsets } from 'react-native-safe-area-context';
//Import Interfaces
import { IListItem } from '../utils/typescript/types.d';
import { IPropsMenu } from '../utils/typescript/props.d';
import { IStateMenu } from '../utils/typescript/state.d';
//A function is used to pass the header height, using hooks.
function withHeightHook(Component: any){
return function WrappedComponent(props: IPropsMenu) {
/*
Returns the frame of the nearest provider. This can be used as an alternative to the Dimensions module.
*/
const frame = useSafeAreaFrame();
/*
Returns the safe area insets of the nearest provider. This allows manipulating the inset values from JavaScript. Note that insets are not updated synchronously so it might cause a slight delay for example when rotating the screen.
*/
const insets = useSafeAreaInsets();
return <Component {...props} headerHeight={getDefaultHeaderHeight(frame, false, insets.top)} />
}
}
class Menu extends React.Component<IPropsMenu, IStateMenu> {
constructor(props: IPropsMenu) {
super(props);
this.state = {
menu: [
{
name: 'screen1.name',
fallbackName: 'Screen 1',
icon: 'dice-multiple-outline',
iconFocused: 'dice-multiple',
onPress: this.props.navigation.navigate.bind(this, 'screen1')
},
{
name: 'screen2.name',
fallbackName: 'Screen 2',
icon: 'drama-masks',
iconFocused: 'drama-masks',
onPress: this.props.navigation.navigate.bind(this, 'screen2')
}
]
}
}
renderItem = (item : IListItem) => {
const { i18n } = this.props.state.routes[0].params;
return (
<DrawerItem
label={ i18n.t(item.name, item.fallbackName) }
onPress={ item.onPress ? item.onPress: () => {} }
icon={ ({ focused, color, size }) => <List.Icon color={color} style={[styles.icon, {width: size, height: size }]} icon={(focused ? item.iconFocused : item.icon) || ''} /> }
/>
);
};
render() {
const { headerHeight } = this.props;
const { menu } = this.state;
const { Theme } = this.props.state.routes[0].params;
return (
<View>
<View style={{
backgroundColor: Theme.colors.primary,
height: headerHeight ?? 0,
}}>
<View style={{
flex: 1,
flexDirection: 'column',
justifyContent: 'flex-end',
}}>
<View style={{
flexDirection: 'row',
alignItems: 'center',
marginBottom: 5,
marginLeft: 5
}}>
<Title style={{ color: Theme.colors.text, marginLeft: 5 }}>
Title
</Title>
</View>
</View>
</View>
<FlatList
data={menu}
keyExtractor={item => item.name}
renderItem={({item}) => this.renderItem(item)}
/>
</View>
);
};
}
export default withHeightHook(Menu);
const styles = StyleSheet.create({
icon: {
alignSelf: 'center',
margin: 0,
padding: 0,
height:20
},
logo: {
width: 24,
height: 24,
marginHorizontal: 8,
alignSelf: 'center'
},
});
The solution to my issue was to encapsulate the drawer component in a native stack component. The 'Hamburger' icon works as expected, thanks for all the help and suggestions.
// Import Screens
import DrawRouter from './DrawRouter';
const Stack = createNativeStackNavigator<RootStackParamList>();
export default (): React.ReactElement => {
return (
<NavigationContainer>
<Stack.Navigator screenOptions={{ headerShown: false }}>
<Stack.Screen name="Main" component={DrawRouter} />
</Stack.Navigator>
</NavigationContainer>
);
};
Add the toogleDrawer() method to your onPress event on your Drawer.Navigator component:
onPress={()=> navigation.toggleDrawer()
Hello guys so I wanted to add a navigation DRAWER inside my main screen and I did not know how to nest it with the already existing stack navigator ,
this is my navigation component :
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
import ProductsOverviewScreen from "../screens/shop/ProductsOverviewScreen";
import ProductDetails from "../screens/shop/ProductDetailScreen";
import { HeaderButtons,Item } from "react-navigation-header-buttons";
import HeaderButton from '../components/UI/HeaderButton'
import CartScreen from "../screens/shop/CartScreen";
import OrdersScreen from "../screens/shop/OrdersScreen";
const RootNavigation=()=> {
const Stack = createStackNavigator();
const NavigationDrawerStructure = (props)=> {
//Structure for the navigatin Drawer
const toggleDrawer = () => {
//Props to open/close the drawer
props.navigationProps.toggleDrawer();
};
return (
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity onPress={()=> toggleDrawer()}>
{/*Donute Button Image */}
<Image
source={{uri: 'https://raw.githubusercontent.com/AboutReact/sampleresource/master/drawerWhite.png'}}
style={{ width: 25, height: 25, marginLeft: 5 }}
/>
</TouchableOpacity>
</View>
);
}
const screenOptions ={
headerShown:true,
headerStyle: {
backgroundColor: 'white',},
headerTintColor: 'aqua',
headerTitleStyle: {
fontWeight: 'bold',
},
};
return(
<NavigationContainer>
<Stack.Navigator initialRouteName='ProductsOverview' screenOptions={screenOptions}>
<Stack.Screen name='ProductsOverview' component={ProductsOverviewScreen} options={({navigation,route})=>({title:'All Products',headerTitleStyle:{fontFamily:'open-sans-bold'},
headerRight:()=>( <HeaderButtons HeaderButtonComponent={HeaderButton}><Item title ='Cart' iconName='md-cart' onPress={()=>{navigation.navigate('CartScreen')}}/></HeaderButtons>)})}/>
<Stack.Screen name='ProductsDetail' component={ProductDetails} options={({route})=>({title:route.params.productTitle,headerTitleStyle:{fontFamily:'open-sans-bold'}})} />
<Stack.Screen name='CartScreen' component={CartScreen} options={{title:'Cart Items', headerTitleStyle:{fontFamily:'open-sans-bold'}}} />
<Stack.Screen name='OrdersScreen' component={OrdersScreen} options={{title:'Orders '}}/>
</Stack.Navigator>
</NavigationContainer>
)
}
export default RootNavigation;
and this is my app.js
import { StatusBar } from 'expo-status-bar';
import { StyleSheet } from 'react-native';
import {createStore , combineReducers} from 'redux';
import { Provider} from 'react-redux';
import AppLoading from 'expo-app-loading';
import * as Font from 'expo-font';
import productsReducer from './store/reducers/products';
import {composeWithDevTools} from 'redux-devtools-extension'
import RootNavigation from './navigation/ShopNavigation';
import cartReducer from './store/reducers/cart'
import { useState } from 'react';
import ordersReducer from './store/reducers/orders'
const rootReducer=combineReducers({
products: productsReducer,
cart: cartReducer,
orders:ordersReducer,
});
const store = createStore(rootReducer,composeWithDevTools());
const fetchFonts=()=>{
return Font.loadAsync({
'open-sans': require('./assets/fonts/OpenSans-Regular.ttf'),
'open-sans-bold': require('./assets/fonts/OpenSans-Bold.ttf')
})
}
export default function App() {
const [fontLoaded,setfontLoaded]= useState(false);
if (!fontLoaded) {
return (
<AppLoading
startAsync={fetchFonts}
onFinish={()=>setfontLoaded(true)}
onError={console.warn}
/>
);
}
return (
<Provider store={store}>
<RootNavigation />
</Provider>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
can you give me an idea how to nest them together I tried using the docs but still full of errors
and Thanks
Drawer Navigator must be a parent to both Stack and Tab navigators. With that knowledge, let we refactor our code as below:
import React from "react";
import { NavigationContainer } from "#react-navigation/native";
import { createStackNavigator } from "#react-navigation/stack";
import ProductsOverviewScreen from "../screens/shop/ProductsOverviewScreen";
import ProductDetails from "../screens/shop/ProductDetailScreen";
import { HeaderButtons, Item } from "react-navigation-header-buttons";
import HeaderButton from "../components/UI/HeaderButton";
import CartScreen from "../screens/shop/CartScreen";
import OrdersScreen from "../screens/shop/OrdersScreen";
import { createDrawerNavigator } from "#react-navigation/drawer";
const RootNavigation = () => {
const Stack = createStackNavigator();
const Drawer = createDrawerNavigator();
const AppStack = () => (
<Stack.Navigator
initialRouteName="ProductsOverview"
screenOptions={screenOptions}
>
<Stack.Screen
name="ProductsOverview"
component={ProductsOverviewScreen}
options={({ navigation, route }) => ({
title: "All Products",
headerTitleStyle: { fontFamily: "open-sans-bold" },
headerRight: () => (
<HeaderButtons HeaderButtonComponent={HeaderButton}>
<Item
title="Cart"
iconName="md-cart"
onPress={() => {
navigation.navigate("CartScreen");
}}
/>
</HeaderButtons>
),
})}
/>
<Stack.Screen
name="ProductsDetail"
component={ProductDetails}
options={({ route }) => ({
title: route.params.productTitle,
headerTitleStyle: { fontFamily: "open-sans-bold" },
})}
/>
<Stack.Screen
name="CartScreen"
component={CartScreen}
options={{
title: "Cart Items",
headerTitleStyle: { fontFamily: "open-sans-bold" },
}}
/>
<Stack.Screen
name="OrdersScreen"
component={OrdersScreen}
options={{ title: "Orders " }}
/>
</Stack.Navigator>
);
return (
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen name="MainStack" component={AppStack} />
</Drawer.Navigator>
</NavigationContainer>
);
};
export default RootNavigation;
I omitted component code below as can't access drawer.
const NavigationDrawerStructure = (props)=> {
//Structure for the navigatin Drawer
const toggleDrawer = () => {
//Props to open/close the drawer
props.navigationProps.toggleDrawer();
};
return (
<View style={{ flexDirection: 'row' }}>
<TouchableOpacity onPress={()=> toggleDrawer()}>
{/*Donute Button Image */}
<Image
source={{uri: 'https://raw.githubusercontent.com/AboutReact/sampleresource/master/drawerWhite.png'}}
style={{ width: 25, height: 25, marginLeft: 5 }}
/>
</TouchableOpacity>
</View>
);
}
Here a minified version of working implementation
https://snack.expo.dev/#emmbyiringiro/69dc5b
when i swipe right my drawer open but i want to open it using a button in the header i did a code but i have this error undefined is not a object (evaluating 'navigation.openDrawer')
thats my app.js code :
import {createStackNavigator} from 'react-navigation-stack';
import { createAppContainer } from 'react-navigation';
import Home from './components/login'
import Inscription from './components/inscription'
import signup from './components/signup'
import mp from './components/motdepasse'
import ch from './components/choice'
import mn from './components/menu1'
import drawer from './components/drawerapp'
import React, { Component } from 'react';
import { Image, StyleSheet, Text, TouchableOpacity, } from 'react-native';
import Icon from 'react-native-vector-icons/Entypo'
const Navigator = createStackNavigator({
Home:{screen: Home},
Profil:{screen: Inscription},
signup:{screen: signup, navigationOptions: { header: null }},
mp:{screen: mp},
ch:{screen: ch},
mn:{screen: mn},
drawer:{screen: drawer,navigationOptions: { title:"votre travail",
headerStyle:{backgroundColor:'#8B0000'},
headerTitleStyle: {
fontWeight: 'bold',
color:'white',
},
headerLeft: ({ navigation }) => (
<TouchableOpacity onPress={() => navigation.openDrawer()} >
<Icon name={'menu'} size={28} color={'white'} style={{marginRight:10}}/>
</TouchableOpacity>
),}},
}
);
const App = createAppContainer(Navigator);
export default App;
and that's my appdrawer code:
function CustomDrawerContent(props) {
return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<DrawerItem label="Help" onPress={() => alert('Link to help')} />
<DrawerItem
label="Close drawer"
onPress={() => props.navigation.closeDrawer()}
/>
</DrawerContentScrollView>
);
}
const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
<Drawer.Navigator drawerContent={props => CustomDrawerContent(props)}>
<Drawer.Screen name="Feed" component={mn} />
<Drawer.Screen name="Article" component={Article} />
</Drawer.Navigator>
);
}
export default class drawerapp extends React.Component {
render(){
const {navigate} = this.props.navigation;
return (
<NavigationContainer>
<MyDrawer />
</NavigationContainer>
);
}}
my work perfectly fine until i click on the left header button and the error appear
u are getting the navigation prop in wrong place, headerLeft does not give navigation prop, so u have to get it from navigationOptions...
change the navigator code as below..
const Navigator = createStackNavigator({
Home:{screen: Home},
Profil:{screen: Inscription},
signup:{screen: signup, navigationOptions: { header: null }},
mp:{screen: mp},
ch:{screen: ch},
mn:{screen: mn},
drawer:{screen: drawer,
navigationOptions: ({navigation}) => ({
title:"votre travail",
headerStyle:{backgroundColor:'#8B0000'},
headerTitleStyle: {
fontWeight: 'bold',
color:'white',
},
headerLeft: () => (
<TouchableOpacity onPress={() => navigation.openDrawer()} >
<Icon name={'menu'} size={28} color={'white'} style={{marginRight:10}}/>
</TouchableOpacity>
),
}),
},
});
my head is crack up now with this navigation, i watched several videos about this and follow them but still hitting the same error of undefined is not an object error for this.props.navigation.navigate
here is my code basically
App.js
import React from 'react';
import { Container, Body, Header, Title, Content, List, ListItem, Text, Left, Right, Icon, Footer, FooterTab, Button} from 'native-base';
import { createStackNavigator } from 'react-navigation';
import { YellowBox } from 'react-native';
YellowBox.ignoreWarnings(['Warning: isMounted(...) is deprecated', 'Module RCTImageLoader']);
import Home from './Home';
import Details from './Details';
export default createStackNavigator(
{
Home: {
screen: Home
},
Details: {
screen: Details
}
},
{
initialRouteName: 'Home',
}
);
Here is my Home.js
import React, { Component } from 'react';
import { Container, Body, Header, Title, Content, List, ListItem, Text, Left, Right, Icon, Footer, FooterTab, Button} from 'native-base';
class Home extends Component {
constructor(){
super();
this.state = {
data: []
};
}
getData(){
return fetch('https://testdata.com')
.then((response) => response.json())
.then((responseJson) => {
console.log(JSON.stringify(responseJson.result));
this.setState({data:responseJson.result});
//alert(responseJson.result[1].name);
//return responseJson.result[1].name;
})
.catch((error) => {
console.error(error);
});
}
componentDidMount(){
this.getData();
}
static navigationOptions = ({navigation}) => {
const {state, navigate} = navigation;
return {
title: "test",
headerStyle: {
backgroundColor: '#4050B5',
},
headerTintColor: '#fff',
headerTitleStyle: {
fontWeight: 'bold'
},
};
};
render() {
let yytCardData = this.state.data.map(function(cardData, i){
return (
<ListItem key={cardData.ver}>
<Left>
<Text>{cardData.name}</Text>
</Left>
<Right>
<Icon name="arrow-forward" />
<Button transparent info onPress={() => this.props.navigation.navigate('Details')}>
<Text>Info</Text>
</Button>
</Right>
</ListItem>
)
});
return (
<Container>
<Content>
<List>
{yytCardData}
</List>
</Content>
<Footer>
<FooterTab>
<Button vertical active>
<Icon name="apps" />
<Text>Title List</Text>
</Button>
<Button vertical>
<Icon name="search" />
<Text>Search</Text>
</Button>
</FooterTab>
</Footer>
</Container>
);
}
}
export default Home
and a very empty Details.js
import React, { Component } from 'react';
import { Container, Header, Content, List, ListItem, Text, Left, Right, Icon } from 'native-base';
class Details extends Component {
render() {
return(
<Container>
<Header />
<Content padder>
<Card transparent>
<CardItem>
<Body>
<Text>
This is just a transparent card with some text to boot.
</Text>
</Body>
</CardItem>
</Card>
</Content>
</Container>
);
}
}
export default Details;
i am not sure which part is incorrect in this case but doing just a simple navigation sounds very complex
You need to bind your function using the arrow function in your render method.
let yytCardData = this.state.data.map((cardData, i) => { // Replace function with arrow function
The issue is with scope in Home component this.state.data.map(function(cardData, i){. If you don't want to use arrow function then you can use the same function but just assigning this to a local variable and use that
let yytCardData = this.state.data.map(function(cardData, i){
let that = this;
return (
<ListItem key={cardData.ver}>
<Left>
<Text>{cardData.name}</Text>
</Left>
<Right>
<Icon name="arrow-forward" />
<Button transparent info onPress={() => that.props.navigation.navigate('Details')}>
<Text>Info</Text>
</Button>
</Right>
</ListItem>
)
});
If you want to use arrow function then follow what Pritish Vaidya mentioned
I am trying to add a button to get to my settings component (index.js) from my home component(main screen). For some reason this is not working, I have added different screens before and copied them as an example but I am not having any luck with this. I tripled checked the imports and they all seem good.
Here is what my AppNavigator.js looks like:
import React, { Component } from "react";
import { StatusBar, Platform } from "react-native";
import { connect } from "react-redux";
import { Scene, Router } from "react-native-router-flux";
import Login from "./components/common/login/";
import SignIn from "./components/common/signIn/";
import Register from "./components/common/register/";
import DriverStartupService from
"./components/driver/startupServices";
import DriverRootView from "./components/driver/rootView";
import DriverHome from "./components/driver/home";
import RideRequest from "./components/driver/rideRequest";
import PickRider from "./components/driver/pickRider";
import StartRide from "./components/driver/startRide";
import DropOff from "./components/driver/dropOff";
import RateRider from "./components/driver/rateRider";
import Settings from "./components/driver/settings";
import { statusBarColor } from "./themes/base-theme";
import { getAppConfig } from './actions/appConfig';
const RouterWithRedux = connect()(Router);
class AppNavigator extends Component {
static propTypes = {
driverJwtAccessToken: React.PropTypes.string
};
componentWillMount() {
console.log('Getting App Config');
this.props.getAppConfig();
}
render() {
return (
<RouterWithRedux>
<Scene key="root">
<Scene
key="login"
component={Login}
hideNavBar
initial={!this.props.driverJwtAccessToken ? true : false}
/>
<Scene key="signIn" component={SignIn} />
<Scene key="register" component={Register} />
<Scene key="driverRootView" component={DriverRootView}>
<Scene key="driverHome" component={DriverHome} />
<Scene key="rideRequest" component={RideRequest} />
<Scene key="pickRider" component={PickRider} />
<Scene key="startRide" component={StartRide} />
<Scene key="dropOff" component={DropOff} />
<Scene key="rateRider" component={RateRider} />
<Scene key="settings" component={Settings} />
</Scene>
<Scene
key="driverStartupService"
component={DriverStartupService}
hideNavBar
initial={this.props.driverJwtAccessToken}
/>
</Scene>
</RouterWithRedux>
);
}
}
function bindAction(dispatch) {
return {
getAppConfig: () => dispatch(getAppConfig())
};
}
const mapStateToProps = state => ({
driverJwtAccessToken: state.driver.appState.jwtAccessToken
});
export default connect(mapStateToProps, bindAction)(AppNavigator);
Here is the action on my home component (index.js):
import React, { Component } from "react";
import { connect } from "react-redux";
import {
View,
Platform,
TouchableOpacity,
Dimensions,
BackAndroid
} from "react-native";
import {
Content,
Text,
Header,
Button,
Icon,
Title,
Left,
Right,
Body,
Container
} from "native-base";
import { Actions, ActionConst } from "react-native-router-flux";
import {
changePageStatus,
currentLocationDriver
} from "../../../actions/driver/home";
import { logOutUserAsync } from "../../../actions/common/signin";
import styles from "./styles";
import commonColor from "../../../../native-base-
theme/variables/commonColor";
const { width, height } = Dimensions.get("window");
function mapStateToProps(state) {
return {
tripRequest: state.driver.tripRequest,
fname: state.driver.user.fname,
jwtAccessToken: state.driver.appState.jwtAccessToken
};
}
class DriverHome extends Component {
static propTypes = {
logOutUserAsync: React.PropTypes.func,
jwtAccessToken: React.PropTypes.string,
currentLocationDriver: React.PropTypes.func,
openDrawer: React.PropTypes.func
};
constructor(props) {
super(props);
this.state = {
flag: true
};
}
handleLogOut() {
this.props.logOutUserAsync(this.props.jwtAccessToken);
}
componentDidMount() {
BackAndroid.addEventListener("hardwareBackPress", () => {
Actions.pop();
});
}
render() {
// eslint-disable-line class-methods-use-this
return (
<Container>
<Header
androidStatusBarColor={commonColor.statusBarColorDark}
style={styles.iosHeader}
iosBarStyle="light-content"
>
<Left>
<Button transparent>
<Icon
name="ios-power"
style={styles.logoutLogo}
onPress={() => this.handleLogOut()}
/>
</Button>
</Left>
<Body>
<Title
style={
Platform.OS === "ios"
? styles.iosHeaderTitle
: styles.aHeaderTitle
}
>
Hero Home
</Title>
</Body>
<Right>
<Button transparent onPress={() => {
console.log('settings button')
Actions.settings()}}>
<Icon
name="ios-settings"
style={styles.logoutLogo}
/>
</Button>
</Right>
</Header>
<Content />
<View style={styles.detailsContainer}>
<Text style={styles.place}>
Please wait for a Patient request...
</Text>
</View>
<View
style={{
flex: 10,
flexDirection: "row",
alignItems: "flex-end",
justifyContent: "flex-end",
marginRight: 5,
marginTop: height - 150,
marginLeft: width - 40
}}
>
<TouchableOpacity
style={{ flexDirection: "row" }}
onPress={() => this.props.currentLocationDriver()}
>
<Icon name="ios-locate-outline" style={{ fontSize: 40, backgroundColor: 'transparent' }} />
</TouchableOpacity>
</View>
</Container>
);
}
}
function bindActions(dispatch) {
return {
openDrawer: () => dispatch(openDrawer()),
changePageStatus: newPage => dispatch(changePageStatus(newPage)),
logOutUserAsync: jwtAccessToken =>
dispatch(logOutUserAsync(jwtAccessToken)),
currentLocationDriver: () => dispatch(currentLocationDriver())
};
}
export default connect(mapStateToProps, bindActions)(DriverHome);
I can see the console.log message in my terminal so I know the onPress is working.. Any help would be appreciated. Been stuck for hours. I would be happy to share more of the code if needed. Thanks!