react native 官网的主推方案就是一个单独的导航库 react-navigation ,使用 react-navigation 6.x ,官方文档:Getting started | React Navigation
yarn add @react-navigation/native // 安装导航库
yarn add react-native-screens react-native-safe-area-context // 安装导航的依赖库
yarn add @react-navigation/native-stack // 安装栈路由
yarn add @react-navigation/bottom-tabs // 安装tab路由
yarn add @react-navigation/drawer // 安装抽屉路由
路由配置文件:router/index.tsx
项目中所有需要进行路由跳转的页面都需要在这里进行配置,否则无法跳转成功。
import * as React from 'react';
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import {TouchableOpacity} from 'react-native';
import {ChevronLeft} from 'react-native-feather';
const Stack = createNativeStackNavigator();
// 把需要跳转的页面先引入进来
import {Login} from '@/screens/Login/Login';
import {TabNavigator} from '@/components/TabNavigator';
import {Message} from '@/screens/My/component/Message';
function Route() {
return (
({
headerShown: true, // 显示标题栏
headerTitleStyle: {fontSize: 16, fontWeight: 'bold', color: '#333333'}, // 修改标题文本样式
headerTitleAlign: 'center', // 标题居中
headerStyle: {backgroundColor: '#eee'}, // 修改标题栏背景颜色
// 修改左侧返回按钮图标样式
headerLeft: () => (
navigation.goBack()}>
),
// 修改右侧按钮图标样式
headerRight: () => (),
})}>
{/* component 是引入的组件名,name 是进行路由跳转时候的name,跳转的时候用的是TabsLayout而不是TabNavigator */}
{/* 放置带tab的页面 */}
{/* 全屏页面 隐藏标题栏 headerShown: false */}
{/* 全屏页面 带标题栏 设置标题 title: '消息通知' */}
);
}
export default Route;
其他页面进行路由跳转
1. 在 ts 中使用,示例:
上面在router/index.tsx 中,Login 已经配置了路由,这里会自带 navigation ,可以进行路由跳转,如果需要在此文件的其他方法使用,需要把 navigation 传过去
const FormChecked = ({navigation}: any) => {
const submit = () => {
request.post(url, data).then((res) => {
// 这里登录成功,自动跳转到首页
navigation.navigate('TabsLayout')
// 需要传参数的写法,接收在 route.params 里接收
navigation.navigate('TabsLayout', {id: res.data.id})
})
}
return(
)
}
export const Login = ({navigation}:any) => {
// 在这里也可以直接进行跳转
navigation.navigate('TabsLayout')
return (
{/* FormChecked 组件中要用到,需要传navigation过去 */}
);
}
2. 在 html 中使用,示例:
export const Login = ({navigation}:any) => {
return (
);
}
带 tab 的页面:components/TabNavigator.tsx
/**
* 放置带tab的页面
*/
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { Cloud, User } from "react-native-feather";
const Tab = createBottomTabNavigator();
import {Home} from "@/screens/Home/Home"
import {Settings} from "@/screens/Settings/Settings"
export function TabNavigator() {
return (
(
),
}}
/>
(
),
}}
/>
);
}
1. 这里必须要把 NavigationContainer 作为根组件,否则不生效
// 错误的写法, 这里路由就没有生效
测试项目11
// 正确的写法
测试项目11
2. Screen 组件用来定义路由:路由配置、取名、渲染
3. 这里的 initialRouteName 是默认显示的页面,可以理解为首页
退出登录的时候重置导航堆栈,解决React Navigation对屏幕的缓存会保留上一个屏幕的状态和参数,导致重新登录会进入退出前的最后一个画面的问题。
navigation.reset({
index: 0,
routes: [{ name: 'Login' }],
})
navigate(routeName, params)
routeName
: 要导航到的目标路由名称。params
(可选): 要传递给目标屏幕的参数。push(routeName, params)
navigate()
。navigate()
不同的是,push()
可以多次将相同的屏幕推入导航堆栈中。goBack()
headerLeft
或自定义按钮一起使用。pop()
goBack()
类似,但是 pop()
可以处理更复杂的导航场景,如从堆栈中移除多个屏幕。replace(routeName, params)
reset(state)
setParams(params)
params
: 要更新的参数对象。isFocused()
addListener(type, callback)
type
: 生命周期事件类型。例如: focus
, blur
, beforeRemove
等等。callback
: 将在事件发生时调用的回调函数。dangerouslyGetParent()
dispatch(action)
canGoBack()
emit(eventName, data)