【问题标题】:Getting undefined is not an object (evaluating '_this.props.navigation')获得未定义不是评估 _this.props.navigation 的对象
【发布时间】:2017-12-26 20:10:02
【问题描述】:

我正在使用 DrawerNavigator,我有 3 页:Router pagemainScreenphotos page
我制作了一个标题导航栏区域,我使用这个<TouchableHighlight onPress={() => this.props.navigation.navigate('DrawerOpen')}>在mainScreen中打开抽屉菜单并将其用于照片页面,mainScreen中的菜单正常,但是当我在照片页面中单击<TouchableHighlight onPress={() => this.props.navigation.navigate('DrawerOpen')}>时,我收到了这个错误:
我该如何解决?

我的照片页面:

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;

主屏幕:

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>

        )
    }
}

【问题讨论】:

  • 嗯,我认为很明显您没有在照片页面中包含所有内容。请使用这两个文件中的所有代码更新您的代码,以便我们查看缺少的内容。
  • 这是我的所有代码,没有我的风格,我从 ` ` 传递了我的照片页面,我可以在照片页面中看到照片文本和后退按钮,但我如果需要,应该添加我的路由器页面吗?
  • 我也遇到了同样的问题我 import { useNavigation } from '@react-navigation/native'; const navigation = useNavigation();这对我有帮助。

标签: react-native react-navigation


【解决方案1】:

如果您在子组件中使用导航,请不要忘记在 props 中将导航发送给子组件

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

像这样访问子组件

    props.navigation.navigate("ScreenName")

【讨论】:

  • 完美解决方案!拯救了我的一天:)
  • 如果导航根本不适合您 - 所有这些都假设在您的App() 中有&lt;NavigationContainer&gt;&lt;YourNavigatorComponent /&gt;&lt;/NavigationContainer&gt;(是的,只是导航组件,而不是“主页““主要”或类似的东西) - 其中YourNavigatorComponent是返回&lt;Stack.Navigator&gt;...的东西,您链接“主页”/“主要”组件/屏幕和其他,只是把它放在那里,因为我认为这更多自动的,不是。
  • 正确的解决方案谢谢。
【解决方案2】:

也许我忽略了一些东西,但它看起来只是一个简单的 Javascript 错误。您正在销毁纯组件中的道具MyNavScreen

const MyNavScreen = ({ navigation }) => (

这意味着您无权访问this.props。您只需访问已解构的道具navigation。因此,未定义错误的原因实际上是未定义的:

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

如果你改为直接使用navigation,它应该可以工作:

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

mainScreen 上,您很好,因为它不是带有解构参数的纯组件。所以你仍然可以在render() 中访问this.props

如果这给您带来麻烦,您应该关注destructing

【讨论】:

  • 谢谢亲爱的@michael-cheng, Solved.and whitch 方法更好吗?我的代码还好吗?我可以继续吗?或者我应该更改为 reder() 模式并添加 this.props?
  • @SedricHeidarizarei 我认为解构没有“更好的方法”。它只是一个帮助使代码更具可读性的工具。是否使用它取决于您的风格和团队的风格。这是我的意见,我当然不是 Javascript 方面的专家,所以请相信我的话。
  • @SedricHeidarizarei 至于纯组件,使用它们是有充分理由的。网上有很多关于何时以及如何最好地使用它们的文章。我建议花一点时间阅读它们,因为它会让你更好地理解 React 以及如何构建你的代码。甚至还有a question on StackOverflow covering this topic 涉及更多细微差别。例如,您的photos page 具体是一个功能性无状态组件
  • 感谢此解决方案有效。以前我被困在这个问题上,因为我使用非渲染方法来使用导航道具。
【解决方案3】:

绑定这个对我有用

在我的情况下,当我将this 绑定到在构造函数中调用prop 的方法时,它起作用了。

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

对于功能组件,请尝试使用 useNavigation 挂钩进行深度导航

或者直接使用箭头函数

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

因为当您使用表达式函数时,它会创建它自己的作用域


【讨论】:

    【解决方案4】:

    试试这个:

    import { withNavigation } from 'react-navigation';
    

    withNavigation 为整个项目/应用程序提供道具,您可以从任何地方访问导航道具。

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

    最后,

    export default withNavigation(MyPhotosHomeScreen);
    

    看看这个https://reactnavigation.org/docs/en/connecting-navigation-prop.html

    【讨论】:

      【解决方案5】:

      如果您在子元素中使用 TouchableOpacity/Height,请将其传递给 this.props.onPress,如下所示:

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

      然后像这样在你的父组件中调用 onPress 函数:

      <Parent onPress={this.Handlepress} />
      

      【讨论】:

        【解决方案6】:

        这就是我在 React Navigation 2 版本中的做法:我从 StackNavigator 调用 openDrawer() 方法,它是 DrawerNavigator 的子导航器。

        这是我的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】:

          如果要在子组件中导航,则必须在子组件中获取道具。

          假设您有 3 个组件 - Comp_1、Comp_2、Comp_3,并且您想要从 Comp_2 -> Comp_3 导航。为此,请按以下步骤操作。

          1. 在 Comp_1 组件中传递道具。像这样

            &lt;Comp_2 navigation={this.props.navigation}/&gt;

          2. 现在在 Comp_2 中,我们可以像这样从 Comp_2 -> Comp_3 导航。

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

          例如——

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

          【讨论】:

            【解决方案8】:

            在您尝试进入另一个视图的组件中,您必须通过在导入组件的 onPress 中使用它来发送对象导航

            例子

            在视图中实现组件 <CardComponent title="bla bla" navigation={this.props.navigation} />

            组件模板

            <View> <Button title={this.props.title} onPress={()=> this.props.navigation.navigate("anotherAwesomeView")}/> </View>

            此问题是因为您尝试实现的组件未在 stackNavigation 上定义,因此您无法使用方法导航,并且通过参数传递此对象导航器您可以访问它

            【讨论】:

              【解决方案9】:

              我在使用标题组件时遇到了同样的问题

              现在您可以像这样在其他组件中使用导航变量

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

              编码愉快 :)

              【讨论】:

                【解决方案10】:

                功能组件以 props 作为参数。 你应该试试这个

                const MyNavScreen = ({props}) =>
                

                然后调用没有这个关键字的props

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

                【讨论】:

                  【解决方案11】:

                  我遇到了同样的问题。我就是这样解决的:

                  1. 验证所有的构造函数都有“props”有参数
                  2. 使用构造函数中的函数this.props.navigation.navigate 绑定函数,如下所示:this.your_function = this.your_function.bind(this)

                  【讨论】:

                    【解决方案12】:

                    当你在 createStackNavigator 中定义 screen 时,它默认传递一个称为导航的道具, 像这样的 => navigation={this.props.navigation}

                    但是当你使用this.props.navigation.navigator("YOUR SCREEN ") 并且没有在 createStackNavigator 中定义此屏幕,您必须将 navigation={this.props.navigation} 传递给您在 createStackNavigator 中定义的屏幕,然后您才能在组件中使用它。

                    【讨论】:

                      【解决方案13】:

                      类 ProductScreen 扩展组件 {

                      导出默认 ProductScreen; // 确保底部提到这一行

                      叫这个

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

                      【讨论】:

                        【解决方案14】:

                        试试这个,你可能会错过从 '@react-navigation/native' 导入 useNavigation();

                        import { useNavigation } from '@react-navigation/native';
                        
                        function NotificationsScreen() {
                        const navigation = useNavigation(); 
                        return(
                        <Button
                                onPress={() => navigation.navigate('Notifications')}
                                title="Go to notifications"
                              />
                        );
                        }
                        enter code here
                        

                        【讨论】:

                        • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
                        猜你喜欢
                        • 1970-01-01
                        • 1970-01-01
                        • 2019-09-11
                        • 2016-12-04
                        • 2019-09-26
                        • 2019-12-12
                        • 2019-08-16
                        • 2017-01-16
                        • 2020-08-06
                        相关资源
                        最近更新 更多