路由
下载navigation依赖
npm i @react-navigation/native
下载栈路由依赖
npm i @react-navigation/native-stack
npm i @react-navigation/elements # 如果缺少对应的模块就按照提示安装对应的模块
下载路由回收(普通屏幕和刘海屏)
npm i react-native-screens react-native-safe-area-context
路由配置
import React from 'react'
import { View, Text } from 'react-native'
import { NavigationContainer } from '@react-navigation/native'
import { createNativeStackNavigator } from '@react-navigation/native-stack'
const Stack = createNativeStackNavigator()
const Cart = () => {
return (<View><Text>我是购物车</Text></View>)
}
const Detil = () => {
return (<View><Text>我是详情页</Text></View>)
}
const Home = () => {
return (<View><Text>主页</Text></View>)
}
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator>
// 没有配置的情况下第一个路由Stack.Screen显示为首页
// 路由写法1
<Stack.Screen name='Home' component={ Home }></Stack.Screen>
// 路由写法2 (必须为函数返回一个React组件并且需要传入props)
<Stack.Screen name='Detil'>
{props => <Detil {...props}/>}
</Stack.Screen>
<Stack.Screen name='Cart' component={ Cart }></Stack.Screen>
</Stack.Navigator>
</NavigationContainer>
)
}
export default App
配置项
在Stack.Navigator组件内设置属性让子路由拥有默认属性
// code...
const App = () => {
return (
<NavigationContainer>
<Stack.Navigator
initialRouteName='Detail' // 设置默认显示的页面(首页)
screenOptions={{
title:'Home', // 设置标题栏标题内容
headerStyle: {
backgroundColor: '#ff6600' // 设置标题栏背景颜色
},
headerTintColor: '#ffffff', // 标题文字颜色
headerTitleAlign: 'center', // 标题文字居中方式
headerShown: false // 是否显示标题栏
}}
>
<Stack.Screen
name='Home'
component={ Home }
options={{ title:'我是首页', headerShown: true }} // 子路由中也可以独立设置属性
></Stack.Screen> // 会对Stack.Navigator的属性覆盖
<Stack.Screen name='Detil'>
{props => <Detil {...props}/>}
</Stack.Screen>
</Stack.Navigator>
</NavigationContainer>
)
}
路由跳转
通过useNavigation的hooks来创建导航器
import React from 'react'
import {View, Text} from 'react-native'
import style from './style'
import { useNavigation } from '@react-navigation/native'
const Home = () => {
// 通过useNavigation创建出一个导航器 目的是为了通过它实现路由跳转
const navigation = useNavigation()
return (
<View>
// 这里的跳转的参数为对应路由中的name属性
<Text onPress={()=>navigation.navigate('Cart')}> 首页 </Text>
</View>
)
}
export default Home
解构props获取导航器
// 如果是以传递props的方式声明的路由 就可以从props中解构出来导航器而无需使用hooks
<Stack.Screen name='Detil'>
{props => <Detil {...props}/>}
</Stack.Screen>
const Detil = ({navigation}) => {
// 在props中解构出navigation并直接使用
return (
<View>
{/* 这里的跳转的参数为对应路由中的name属性 */}
<Text onPress={()=>navigation.navigate('Home')}> 详情页 </Text>
</View>
)
}
导航器的方法
navigation.goBack() // 后退
navigation.navigate() // 跳转
navigation.push() // 跳转 往路由栈中添加一个页面
navigation.replace() // 跳转 替换路由栈中的一个页面
跳转携带参数
在跳转方法中的第二个参数为需要传递的参数
navigation.navigate('Home', {a: 1, b: 2})
获取跳转携带参数
import React from 'react'
import {View, Text} from 'react-native'
import style from './style'
import { useRoute } from '@react-navigation/native'
const Home = () => {
// 通过useRoute获取到路由信息
const route= useRoute()
console.log(route)
return (
<View>
// 这里的跳转的参数为对应路由中的name属性
<Text> 首页 </Text>
</View>
)
}
export default Home
// 如果是以传递props的方式声明的路由 就可以从props中解构出来route获取路由信息
<Stack.Screen name='Detil'>
{props => <Detil {...props}/>}
</Stack.Screen>
const Detil = props => {
// 在props中解构出route获取跳转时携带的参数
const {route} = props
console.log(route)
return (
<View>
<Text> 详情页 </Text>
</View>
)
}
通过标题栏中原生的后退按钮可以退回上一页(有标题栏的情况下)
<Stack.Screen
name='Cart'
component={Cart}
options={{
title: '购物车',
headerShown: true, // 是否显示标题栏
headerBackTitle: '后退', // 返回按钮的文本仅ios有效
headerBackVisible: true, // 返回按钮是否可见
headerRight: () => <Text>我是右边的组件</Text> // 标题栏右边的内容
}}
></Stack.Screen>