反应本机导航抛出错误“无法读取未定义的属性'navigate'

时间:2020-07-01 15:20:28

标签: react-native react-navigation

我正在运行一个代码,该代码显示各种菜肴的菜单,用户可以在其中按一个菜肴,然后将其带到“菜肴细节”屏幕,以了解有关菜肴的信息。问题在于,当我们点击应用程序时正使用导航,但应用程序抛出了一些错误消息,提示“ TypeError:无法读取未定义的属性'navigate'”。您可以在下面的代码中看到我声明的代码。

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

0 个答案:

没有答案