创建页面跳转时报错 undefined is not an object (this.props.navigation.navigate
学习 React-native 的第一个心得就是要做好踩坑的准备,之前刚入手的时候疯狂红屏,于是各种百度,
终于可以正常运行。
但是还是会经常遇到一些极其难受的问题,今天码代码的时候用的是官方文档推荐的一款导航栏的包,我引用的时候,进行页面跳
转的时候总是会红屏报错
undefined is not an object (this.props.navigation.navigate
上网搜了很多处理方法,但是也都没什么作用;于是开始自己探索,终于发现了解决办法。
我的软件模块是由一个 Home 路由,绑定的 App 模块,App 模块里面又渲染一个 Tab 模块,Tab 模块之内又渲染了一个
ListView, 然后我的目的是通过点击 ListView 的 Item,进行页面跳转。
方法如下:
当绑定的路由模块想要通过该组件内的一个子组件的点击事件到达另一个路由的时候,this.props.navigation,里面的 this 是需要我们由最高模块一层一层传递过来,也就是说我上面的 App->Tab->ListView 需要将 this 一层一层传递过来。
下面我们通过代码来解释一下:
Route;
export default createStackNavigator(
{
Home: App,
Details: Details
},
{
initialRouteName: "Home"
}
);
App.js;
class App extends Component {
static navigationOptions = {
title: "电影列表"
};
render() {
return (
<View style={styles.container}>
<Tab navigation={this.props.navigation} />
</View>
);
}
}
Tab.js
render() {
return (
<TabNavigator tabBarStyle={styles.tab}>
<TabNavigator.Item
selected={this.state.selectedTab === "home"}
title="列表"
titleStyle={styles.tabText}
selectedTitleStyle={styles.selectedTabText}
renderIcon={() => (
<Image
source={require("../images/Other-grey.png")}
style={styles.icon}
/>
)}
renderSelectedIcon={() => (
<Image
style={styles.icon}
source={require("../images/Other.png")}
/>
)}
onPress={() => this.setState({ selectedTab: "home" })}
>
<MovieList navigation={this.props.navigation} />
</TabNavigator.Item>
</TabNavigator>
);
}
可以看到我在 Tab 的 render 里面渲染了一个 MoveList 模块,然后 Tab 中的 navigation={this.props.navigation}已经在>App.js 中传过来了,现在我们再用 MovieList navigation={this.props.navigation}这样的代码,将这个属性再传给>Movelist,最后在 MoveList 这个模块中,如果我们直接用 onPress={() => this.props.navigation.navigate(‘Details’) 依然会报错,这是因为我们一层一层传输过来的this,并没有被引用到,也就是说这个 onPress 里面直接用箭头函数写的 this,并不是我们传输过来的this,我们可以通过一个 bind 属性,将传输过来的 this 绑定到一个自定义函数中。
接下来我们看一眼 MoveList 中引用这个属性的代码
MoveList.js
toDetail(movie) {
this.props.navigation.navigate("Details");
}
renerMovieList(movie) {
return (
<TouchableNativeFeedback onPress={this.toDetail.bind(this)}>
<View style={styles.item}>
<View style={styles.itemImage}>
<Image source={{ uri: movie.images.large }} style={styles.Image} />
</View>
</View>
</TouchableNativeFeedback>
);
}
下面展示一下运行之后的结果: