这个问题困扰了我多时,重点不是我不知道原因,而是不知道怎么解决,花费了我很长时间,但是最终解决了,现在把整个过程记录在这里:
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
模块,详细步骤可以移步这里
但是这四种方案都以失败告终,那个错误还是稳稳当当地出现,我在facebook
的react-native github
上提了issue
也没人,鸟,issue地址
最后的最后,我仔细地研究了一下facebook的f8app这个开源项目的navigator使用,最终发现是因为我在使用footerBar组件的时候没有传入navigator props
于是做了如下更改:
- 在footerBar组件中加入props声明:
export interface propsType {
navigator: Navigator
}
- 当其他页面使用这个组件的时候,传入navigator
<FooterBar navigator={this.props.navigator} />
自此,问题解决了,虽然是一个不太难的bug,但是还是记录一下,在这过程中学到了很多