在上一章中,我们定义了一个堆栈导航器,其有两个路由(Home,Details),但是我们并不知道该如何从Home跳转到Detail页面
如果这是一个web浏览器,我们就可以如下这般定义
<a href="details.html">Go to Details</a>
或者 我们也可以这样定义
<a
onClick={() => {
window.location.href = 'details.html';
}}
>
Go to Details
</a>
下面我们要做一些类似的事情但是并不是使用window.location这种方法,我们将使用传递到我们screen组件中的navigation属性来实现页面的跳转。
跳转到一个新的页面
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
// ... other code from the previous section
我们来分析一下上面的代码
- navigation -在堆栈导航器中,navigation属性会被传递到每一个screen组件中。
- navigate('Details') - 我们调用navigate方法来实现页面的跳转。
如果我们调用navigation.navigate方法跳转到一个我们没有在堆栈导航器中定义的路由的话,就什么事情也不会发生。
现在,加入我们在Details页面,如果我们再次跳转到Details页面会发生什么呢?
多次跳转到同一个路由
function DetailsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details... again"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
运行上面的代码,当你点击“Go to Details”时,什么事情都不会发生,这是因为我们已经在Details页面了。
那我们来假设一下,如果是我们想要添加另一个详情页面呢?这是一个很常见的场景,在这个场景中我们想在同一个Details页面展示不同的数据。为了实现这个 ,我们可以用push来替代navigate。push方法可以直接向堆栈中添加新的路由而无视当前导航历史。
<Button
title="Go to Details... again"
onPress={() => navigation.push('Details')}
/>
这样每次一你调用push,都有向堆栈中添加一个新的路由。同时页面也会刷新。而如果你调用navigate方法,首先他会在堆栈中找是否已存在该路由,如果没有找到它才会向堆栈中添加新路由。
页面回退
堆栈导航器提供的导航头默认包含一个返回按钮,点击按钮可以返回到上一个页面,如果导航堆栈中只有一个页面,也就是说并没有可以返回的页面的时候,这个回退按钮就不显示。
有的时候你可能想要通过编程的方式来触发这个行为,你可以调用navigation.goBack()方法。
function DetailsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details... again"
onPress={() => navigation.push('Details')}
/>
<Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
);
}
在Android中,React Navigation与其物理返回键勾连,当用户点击物理返回键时,会触发goBack()方法,所以这个行为跟用户所设想的是一样的。
另一个常见的需求就是返回到多个页面---比如,如果你的堆栈中有多个页面,你想依次移除页面然后返回到第一个页面上。在这个场景中,我们知道我们想要返回Home页面,所以我们可以使用navigate('Home')(不要使用push,你可以试一试然后观察他们的不同)。
另一种方法就是navigation.popToTop(),这个方法将会返回到堆栈中的第一个页面上(初始页面)
function DetailsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details... again"
onPress={() => navigation.push('Details')}
/>
<Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
<Button title="Go back" onPress={() => navigation.goBack()} />
<Button
title="Go back to first screen in stack"
onPress={() => navigation.popToTop()}
/>
</View>
);
}
.总结
navigtion.navigate('RouteName')会检查该堆栈中是否存在该路由,如果不存在,会向堆栈中添加该路由,如果已经存在则跳转到该路由所指的页面上。
我们可以调用navigation.push('RouteName'),将同样的路由多次添加到堆栈上。
如果存在可返回的页面,则导航头的左边会显示回退按钮,否则不显示。
navigation属性对我们所配置的所有路由页面都可用。