undefined is not an object (evaluating 'this.props.navigator.push')

这个问题困扰了我多时,重点不是我不知道原因,而是不知道怎么解决,花费了我很长时间,但是最终解决了,现在把整个过程记录在这里:


react native 中的navigator组件的使用:

  • 引入
import{ Navigator } from 'react-native'
  • 在页面中使用
  <Navigator
         initialRoute={{ id: 'Home', params: { message: 'travel页面' } }}
         configureScene={(route) => {
             if (route.sceneConfig) {
                 return route.sceneConfig
             }
             return Navigator.SceneConfigs.FloatFromRight
         } }
         renderScene={this.renderView}
   />

具体可以移步这里 下面开始讲述我的踩坑之旅 可以下载我的项目源码进行详细查看,github地址

初始化页面代码:
import * as React from "react";
import {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    Navigator,
    NavigatorIOS
} from 'react-native';
import { HomeView, SpotsView, TravelsView, WriteView, UserView } from './views'

class myApp extends React.Component<any, any>{
    constructor(props: any) {
        super(props)
    }
    /**
     *页面跳转
     */
    renderView(route: any, navigator: any) {
        let routeId = route.id;
        switch (routeId) {
            case 'Home':
                return (
                    <HomeView navigator={navigator} />
                );
            case 'Spots':
                return (
                    <SpotsView {...route.params} navigator={navigator} />
                )
            case 'Travels':
                return (
                    <TravelsView {...route.params} navigator={navigator} />
                )
            case 'Write':
                return (
                    <WriteView {...route.params} navigator={navigator} />
                )
            case 'User':
                return (
                    <UserView {...route.params} navigator={navigator} />
                )
        }
    }


    render() {
        return (
            <Navigator
                initialRoute={{ id: 'Home', params: { message: 'home页面' } }}
                configureScene={(route) => {
                    if (route.sceneConfig) {
                        return route.sceneConfig
                    }
                    return Navigator.SceneConfigs.FloatFromBottom
                } }
                renderScene={(route, navigator) => this.renderView(route, navigator)}
                />
        )
    }
}

export default () => myApp

(2)定义了一个footerBar组件

import * as React from 'react'
import { View, Text, Image, Touchable, TouchableOpacity, Navigator, Dimensions, StyleSheet } from 'react-native'
import * as CONST from '../../CONST'
import { HomeView } from '../../views/home/home.view'
import { SpotsView } from '../../views/spots/spots.view'
import { TravelsView } from '../../views/travels/travels.view'
import { WriteView } from '../../views/write/write.view'
import { UserView } from '../../views/user/user.view'

/**图片的统一引入 */
const homeImg = require('../../../public/index.png')
const spotsImg = require('../../../public/spots.png')
const writeImg = require('../../../public/write.png')
const travelImg = require('../../../public/travels.png')
const userImg = require('../../../public/user.png')

export class FooterBar extends React.Component<any, any>{
    constructor(props: any) {
        super(props)

    }

    /**
     *页面跳转
     */
    navigator() {
        this.props.navigator.push({
            id: 'User',
            params: {
                messgage: 'User page'
            }
        })
    }

    render() {
        return (
            <View style={[styles.footerBarContainer, { width: CONST.WIDTH }]}>
                <TouchableOpacity style={[styles.footerBarItem, { width: CONST.WIDTH / 5 }]}>
                    <Image source={homeImg} style={styles.itemImg} />
                    <Text style={styles.itemText}>首页</Text>
                </TouchableOpacity>
                <TouchableOpacity style={[styles.footerBarItem, { width: CONST.WIDTH / 5 }]}>
                    <Image source={spotsImg} style={styles.itemImg} />
                    <Text style={styles.itemText}>景点</Text>
                </TouchableOpacity>
                <TouchableOpacity style={[styles.footerBarItem, { width: CONST.WIDTH / 5 }]}>
                    <Image source={writeImg} style={styles.itemImg} />
                    <Text style={styles.itemText}>记录</Text>
                </TouchableOpacity>
                <TouchableOpacity style={[styles.footerBarItem, { width: CONST.WIDTH / 5 }]}>
                    <Image source={travelImg} style={styles.itemImg} />
                    <Text style={styles.itemText}>游记</Text>
                </TouchableOpacity>
                <TouchableOpacity style={[styles.footerBarItem, { width: CONST.WIDTH / 5 }]} onPress={this.navigator}>
                    <Image source={userImg} style={styles.itemImg} />
                    <Text style={styles.itemText}>我的</Text>
                </TouchableOpacity>
            </View>
        )
    }
}

然后在其中一个页面的代码如下:

import * as React from 'react'
import { View, Text, Image, Dimensions ,Navigator} from 'react-native'
import { FooterBar } from '../../components'

export class UserView extends React.Component<any, any>{

    constructor(props: any) {
        super(props)
    }
    render() {
        console.warn(this.props, 'uuuu')
        return (
            <View>
                <Text>this is the user page</Text>
                <FooterBar />
            </View>
        )
    }
}

但是在运行项目的时候,总是提示错误:undefined is not an object (evaluating 'this.props.navigator.push')

google了一下,是因为没有正确绑定this对象的原因,于是按照网上的解决方案试了一下:

  • 方案一:将函数自动绑定this对象
<TouchableOpacity style={[styles.footerBarItem, { width: CONST.WIDTH / 5 }]} onPress={this.navigator.bind(this)}>
  • 方案二:在constructor函数上进行this绑定
 constructor(props: any) {
        super(props)
        this.navigator = this.navigator.bind(this)
 }
  • 方案三:使用Es6的箭头函数
   onPress={()=>this.navigator}
  • 方案四:安装autobind-decorator 模块,详细步骤可以移步这里

但是这四种方案都以失败告终,那个错误还是稳稳当当地出现,我在facebookreact-native github上提了issue也没人,鸟,issue地址

最后的最后,我仔细地研究了一下facebook的f8app这个开源项目的navigator使用,最终发现是因为我在使用footerBar组件的时候没有传入navigator props

于是做了如下更改:

  • 在footerBar组件中加入props声明:
export interface propsType {
    navigator: Navigator
}
  • 当其他页面使用这个组件的时候,传入navigator
<FooterBar navigator={this.props.navigator} />

自此,问题解决了,虽然是一个不太难的bug,但是还是记录一下,在这过程中学到了很多

转载于:https://my.oschina.net/sunshinewyf/blog/813908

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值