Getting undefined is not an object evaluating _thi

2020-02-09 01:26发布

问题:

I'm using DrawerNavigator and I have 3 pages: Router page, mainScreen and a photos page,
I maked a header navbar area and I used This <TouchableHighlight onPress={() => this.props.navigation.navigate('DrawerOpen')}> to open Drawer menu in mainScreen and used that for photos page too, menu is ok in mainScreen, But when I click <TouchableHighlight onPress={() => this.props.navigation.navigate('DrawerOpen')}> in photos page, I got this error:
How Can I fix That?

My photos page:

import React from 'react';
import { Button, ScrollView, View, Text, StyleSheet, TouchableHighlight } from 'react-native';
import { DrawerNavigator } from 'react-navigation';
import MaterialIcons from 'react-native-vector-icons/MaterialIcons';
import Icon from 'react-native-vector-icons/FontAwesome'

const MyNavScreen = ({ navigation }) => (
  <View>
    <View style={styles.containerNavbar}>
      <TouchableHighlight onPress={() => this.props.navigation.navigate('DrawerOpen')}>
        <Icon name="bars" size={30} color="#fff" />
      </TouchableHighlight>
      <Text style={styles.navbarTitle}>Photos</Text>
    </View>

    <ScrollView>
      <View><Text>photo</Text></View>
      <Button onPress={() => navigation.goBack(null)} title="Go back" />
    </ScrollView>
  </View>
);

const MyPhotosHomeScreen = ({ navigation }) => (
  <MyNavScreen navigation={navigation} />
);
MyPhotosHomeScreen.navigationOptions = {
  title: 'Photos',
  drawerIcon: ({ tintColor }) => (
    <MaterialIcons
      name="photo"
      size={24}
      style={{ color: tintColor }}
    />
  ),
};
export default MyPhotosHomeScreen;

mainScreen:

export default class MainScreen extends React.Component {
    static navigationOptions = {
        drawerLabel: 'Home',
        drawerIcon: ({ tintColor }) => (
            <MaterialIcons
                name="home"
                size={24}
                style={{ color: tintColor }}
            />
        )
    };

    render() {
        return (
            <View>
                <View style={styles.containerNavbar}>
                    <TouchableHighlight onPress={() => this.props.navigation.navigate('DrawerOpen')}>
                        <Icon name="bars" size={30} color="#fff" />
                    </TouchableHighlight>
                    <Text style={styles.navbarTitle}>mainScreen</Text>
                </View>

                <View>
                    <View style={styles.containerFooter}>
                        <Text style={styles.footerTitle}>Footer</Text>
                    </View>
                </View>
            </View>

        )
    }
}

回答1:

Perhaps I'm overlooking something, but it just looks like a simple Javascript error. You're destructing your props in your pure component MyNavScreen:

const MyNavScreen = ({ navigation }) => (

This means that you don't have access to this.props. You just have access to the destructured prop navigation. Hence the reason for the undefined error as this really is undefined:

<TouchableHighlight onPress={() => this.props.navigation.navigate('DrawerOpen')}>

If you change it instead to use navigation directly, it should work:

<TouchableHighlight onPress={() => navigation.navigate('DrawerOpen')}>

On mainScreen, you are fine because it's not a pure component with destructured arguments. So you still have access to this.props in render().

You should brush up on destructing if this is causing you trouble.



回答2:

Binding this worked for me

In my case it worked when I bind this to the method that calls the prop it in the constructor.

constructor(props){
    super(props);
    this.showDetails = this.showDetails.bind(this);// you should bind this to the method that call the props
}

showDetails(_id){
    this.props.navigation.navigate('Details');
}

Or Simply use arrow function

showDetails = (_id) => {
      this.props.navigation.navigate('Details');
}

because while you use expression function it is going to create it's own scope.



回答3:

If you are using navigation in child component don't forget to send navigation in props to child

    <ChildComponent navigation={this.props.navigation}/>

Access in child component like this

    props.navigation.navigate("ScreenName")


回答4:

If you use TouchableOpacity/Height in your child element, pass it this.props.onPress like this:

<TouchableOpacity onPress={this.props.onPress}/>

Then call the onPress function in your parent component like this:

<Parent onPress={this.Handlepress} />


回答5:

Try this:

import { withNavigation } from 'react-navigation';

withNavigation serves the props all over the project/app, you access the navigation props from anywhere.

and

onPress={() => this.props.navigation.navigate('DrawerOpen')} 

Finally,

export default withNavigation(MyPhotosHomeScreen);

check out this https://reactnavigation.org/docs/en/connecting-navigation-prop.html



回答6:

This is how I have done it in React Navigation 2 release: I call the openDrawer() method from a StackNavigator that is a child navigator of the DrawerNavigator.

This is my DrawerNavigator:

export const Drawer = DrawerNavigator(
    {
        MyAccount: {screen: TabsStack},
    });


export const TabsStack = StackNavigator({

    Tabs: {
        screen: Tabs, navigationOptions: ({navigation}) => ({
            headerLeft: (
                <TouchableOpacity style={{marginLeft: 10, marginTop: 3}}
                                  onPress={() => navigation.openDrawer()}>
                    <Image source={require('./assets/menu_h.png')}/>
                </TouchableOpacity>)
        })


回答7:

i had the same problem when i was using the header component

now you can use the navigation variable in other component like this

<TouchableOpacity onPress={() => { this.props.navigation.navigate("Play");}}>

Happy Codding :)



回答8:

functional components take props as argument. You should try this

const MyNavScreen = ({props}) =>

and then call the props without this key word

onPress = {() => props.navigation.navigate('DrawerOpen')} 


回答9:

I encountered the same problem. That's how I solved it:

  1. Verify that all your constructors have "props" has argument
  2. Bind the function with use the function this.props.navigation.navigate in the constructor like this: this.your_function = this.your_function.bind(this)


回答10:

when you defined screen in createStackNavigator , it by default pass a props called navigation, something like this => navigation={this.props.navigation}

but when you using this.props.navigation.navigator("YOUR SCREEN ") and didn't defined this screen at createStackNavigator you must pass the navigation={this.props.navigation} form the screen that you defined in createStackNavigator and then you can use it in your component .



回答11:

class ProductScreen extends Component {

export default ProductScreen; // make sure bottom this line mention

Call this

  <TouchableOpacity
        onPress = {() => this.props.navigation.navigate('ProductAddScreen')}
        activeOpacity={0.7} style={styles.button}>

       <Text style={styles.message}>{this.state.notFound} </Text>

  </TouchableOpacity>


回答12:

If you want navigation in child component,then you have to get props in child component.

Suppose you have 3 components - Comp_1,Comp_2,Comp_3 and you want to navigate from Comp_2 -> Comp_3. To do this follow these steps.

  1. Pass props in Comp_1 component.Like this

    <Comp_2 navigation={this.props.navigation}/>

  2. Now in Comp_2, we can navigate from Comp_2 -> Comp_3 like this.

    this.props.navigation.navigate('Comp_3');

For example -

<Button onPress = {() => this.props.navigation.navigate('Comp_3')} title = 'Go to Comp_3 Screen' />