【问题标题】:this.props.navigation is undefined when using DrawerNavigator使用 DrawerNavigator 时 this.props.navigation 未定义
【发布时间】:2017-12-16 14:20:06
【问题描述】:

我正在将 'react-navigation' 的 DrawerNavigator 集成到我的项目中,作为 this 文档。但是当我运行该项目时,单击按钮时总是会出现此错误:

TypeError: undefined is not an object (评估 'this.props.navigation.navigate')

当我从左向右滑动时,什么也没有发生,抽屉也没有打开。

我检查了this.props,它总是在控制台中记录空{}。 我尝试了许多解决方案,但仍然无法正常工作。

calculator.js

export default class Calculator extends Component {
    constructor(props) {
        super(props);
    }

    static navigationOptions = {
        drawerLabel: 'Calculator',
        drawerIcon: ({ tintColor }) => (
            <Image
                source={require('./../../res/images/icon_calculator.png')}
                style={[styles.icon, {tintColor: tintColor}]}
            />
        ),
    };

    render() {
        return (
            <View style={styles.container}>
                <View>
                    <Text style={styles.title}>Tip Calculator</Text>
                </View>
                <Button
                    onPress={() => this.props.navigation.navigate("SettingsScreen")}
                    title="Go to settings"
                />
            </View>
        );
    }
}

module.exports = Calculator;

settings.js

export default class Settings extends Component {
    constructor(props) {
        super(props);
    }

    static navigationOptions = {
        drawerLabel: 'Settings',
        drawerIcon: ({ tintColor }) => (
            <Image
                source={require('./../../res/images/icon_settings.png')}
                style={[styles.icon, {tintColor: tintColor}]}
            />
        ),
    };

    render() {
        return (
            <View style={styles.container}>
                <Text>Settings</Text>
                <Button
                    onPress={() => this.props.navigation.goBack()}
                    title="Go back home"
                />
            </View>
        );
    }
}

module.exports = Settings;

navigation.js

import {
    DrawerNavigator
} from 'react-navigation';
import Calculator from './../components/calculator/calculator.js';
import Settings from './../components/settings/settings.js';


const RootDrawer = DrawerNavigator({
    CalculatorScreen: {
        path: '/',
        screen: Calculator
    },
    SettingsScreen: {
        path: '/sent',
        screen: Settings
    }
}, {
    initialRouteName: 'CalculatorScreen',
    drawerPosition: 'left'
});

export default RootDrawer;

App.js

export default class App extends Component<{}> {
  render() {
    return (
      <Calculator/>
    );
  }
}

index.js

import { AppRegistry } from 'react-native';
import App from './App';

AppRegistry.registerComponent('rn_tip_calculator', () => App);

我必须将StackNavigatorDrawerNavigator 一起使用,还是我错过了配置中的某些内容?

完整源码,只是一个简单的示例项目,请看:https://github.com/HCMUS-IceTeaViet-SE/rn_tip_calculator

任何帮助将不胜感激。谢谢!

【问题讨论】:

  • 这是因为您没有“连接”或安装导航到应用程序。在它没有被传递到应用程序之前因为我相信我在这里找到了一个错字...github.com/HCMUS-IceTeaViet-SE/rn_tip_calculator/blob/master/… 你在第 25 行通过的导航器是小写的,不应该是大写的吗?
  • @GavinThomas 所以我必须更改 AppRegistry 以在 app.js 中注册我的 DrawerNavigator 而不是 App 组件?为什么?如果我同时注册它们会怎样?
  • 您不能也不应该同时渲染它们。您应该渲染您的应用程序,然后将 RootDrawer 导入应用程序,然后将其传递给计算器。我明天一定会去看的!

标签: android react-native react-native-android react-navigation


【解决方案1】:

你可以使用 dispatch api https://reactnavigation.org/docs/navigators/navigation-actions

1) 导入导航操作

import { NavigationActions } from 'react-navigation'

2) 调度导航动作:

const navigateAction = NavigationActions.navigate({
    routeName: 'SettingsScreen',
    params: {},
})

this.props.navigation.dispatch(navigateAction)

【讨论】:

  • 好的,我会尝试,但为什么我的代码不起作用?和文档一样
【解决方案2】:

我对 React-Native 还是很陌生,但有时我也会遇到这种情况。

我正在使用 Redux 和堆栈导航器......但这是我的工作示例......

import { StackNavigator } from 'react-navigation'
import { Animated, Easing } from 'react-native'
import LoginScreen from '../Containers/LoginScreen'
import LaunchScreen from '../Containers/LaunchScreen'
import HomeScreen from '../Containers/HomeScreen'
import SignUpScreen from '../Containers/SignUpScreen'
import SettingsScreen from '../Containers/SettingsScreen'
import VehicleCreateScreen from '../Containers/VehicleCreateScreen'
import styles from './Styles/NavigationStyles'

// Manifest of possible screens
const PrimaryNav = StackNavigator({
  LoginScreen: { screen: LoginScreen },
  LaunchScreen: { screen: LaunchScreen },
  HomeScreen: { screen: HomeScreen },
  SignUpScreen: { screen: SignUpScreen },
  SettingsScreen: { screen: SettingsScreen },
  VehicleCreateScreen: { screen: VehicleCreateScreen }
}, {
    // Default config for all screens
    headerMode: 'none',
    initialRouteName: 'LaunchScreen',
    navigationOptions: {
      headerStyle: styles.header
    },
    transitionSpec: {
      duration: 0,
      timing: Animated.timing,
      easing: Easing.step0,
    },
  },


)

export default PrimaryNav

然后从一个未连接到REDUX的组件

import React, { Component } from 'react';
import { Container, Content, List, ListItem, Icon, Text, Button, Left, Right, Badge } from 'native-base';
import { Image } from 'react-native'
import styles from './Styles/SideBarStyle';
// import backgroundImage from '../Images/vw.jpg'

const backgroundImage = require("../Images/vw.jpg");
const drawerImage = require("../Images/dirtyHandsDark.jpg");


export default class SideBar extends Component {
    constructor(props) {
        super(props);
    }
    render() {
        // *********** HERE WE DECLARE AN ARRAY TO RENDER LISTS FROM. THIS COULD ALSO BE LIST OF BIKES FROM STORE.. ***********
        const datas = [
            {
                name: "Home",
                route: "HomeScreen",
                icon: "settings",
                bg: "#C5F442",
            },
            {
                name: "Repair",
                route: "HomeScreen",
                icon: "settings",
                bg: "#C5F442",
            },
            {
                name: "My Profile",
                route: "SettingsScreen",
                icon: "settings",
                bg: "#C5F442",
            },

        ];


        return (
            <Container>
                <Content bounces={false} style={{ flex: 1, backgroundColor: "#fff", top: -1 }}>
                    <Image source={backgroundImage} style={styles.drawerCover}>
                        <Image square style={styles.drawerImage} source={drawerImage} />
                    </Image>
                    <List
                        dataArray={datas}
                        renderRow={data =>
                            // *********** CREATE NEW LIST ITEM ON CLICK NAVIGATE TO APPROPRIATE LISTITEM.SCREEN ***********
                            <ListItem button noBorder onPress={() => this.props.navigation.navigate(data.route)}>
                                <Left>
                                    <Icon active name={data.icon} style={{ color: "#777", fontSize: 26, width: 30 }} />
                                    <Text style={styles.text}>
                                        {data.name}
                                    </Text>
                                </Left>
                                {data.types &&
                                    <Right style={{ flex: 1 }}>
                                        <Badge
                                            style={{
                                                borderRadius: 3,
                                                height: 25,
                                                width: 72,
                                                backgroundColor: data.bg,
                                            }}
                                        >
                                            <Text style={styles.badgeText}>{`${data.types} Types`}</Text>
                                        </Badge>
                                    </Right>}
                            </ListItem>}
                    />
                </Content>
            </Container>
        );
    }
}

你可以看到我引用this.props.navigation.navigate 没问题。 这是我的回购供参考。 https://github.com/GavinThomas1192/motoMechanicMeeKanic/tree/master/App

【讨论】:

  • 感谢您回答我的问题!我尝试了您的解决方案,但它导致“找不到变量:导航”
  • 哎呀我不应该使用 DidUPdate,使用 componentDidMount
  • 还是不行,我已经更新了我的项目的app.jsindex.js,你能看看吗?
  • 在你的 app.js 中, 在扩展组件之后做什么?
  • 尝试通过计算器组件传递导航
【解决方案3】:

发生这种情况是因为我没有将 DrawerNavigator “连接”到我的应用程序。

有两种方法可以实现:

  • 第一种方式:将 DrawerNavigator 注册为应用根组件。在index.js更改:

    来自AppRegistry.registerComponent('rn_tip_calculator', () =&gt; App);

    AppRegistry.registerComponent('rn_tip_calculator', () =&gt; RootDrawer);

    所以你可以删除App.js,因为它现在没用了。

  • 第二种方式:保持注册App组件(在App.js中)作为应用根组件。然后放入App 组件内以“连接”DrawerNavigator 到应用程序。

    export default class App extends Component<{}> {
      render() {
        return (
          <RootDrawer/>
        );
      }
    }
    

document 没有说明如何将导航器连接到应用程序,也没有说明注册组件或将导航器放在根组件中。这让像我这样的新手疯了!

【讨论】:

    猜你喜欢
    • 2018-11-10
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-15
    相关资源
    最近更新 更多