React Native 路由导航 react-navigation 6.x 的使用

路由导航

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 (
    <NavigationContainer>
      <Stack.Navigator
        initialRouteName="Login"
        screenOptions={({navigation}) => ({
          headerShown: true, // 显示标题栏
          headerTitleStyle: {fontSize: 16, fontWeight: 'bold', color: '#333333'}, // 修改标题文本样式
          headerTitleAlign: 'center', // 标题居中
          headerStyle: {backgroundColor: '#eee'}, // 修改标题栏背景颜色
          // 修改左侧返回按钮图标样式
          headerLeft: () => (
            <TouchableOpacity onPress={() => navigation.goBack()}>
              <ChevronLeft width={24} height={24} color="#9C9A9D" />
            </TouchableOpacity>
          ),
          // 修改右侧按钮图标样式
          headerRight: () => (),
        })}>
        {/* component 是引入的组件名,name 是进行路由跳转时候的name,跳转的时候用的是TabsLayout而不是TabNavigator */}
        {/* 放置带tab的页面 */}
        <Stack.Screen
          name="TabsLayout"
          component={TabNavigator}
          options={{headerShown: false}}
        />

        {/* 全屏页面 隐藏标题栏 headerShown: false */}
        <Stack.Screen
          name="Login"
          component={Login}
          options={{headerShown: false}}
        />

        {/* 全屏页面 带标题栏 设置标题 title: '消息通知' */}
        <Stack.Screen
          name="Message"
          component={Message}
          options={{title: '消息通知'}}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

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(
		<View></View>
	)
}

export const Login = ({navigation}:any) => {
    // 在这里也可以直接进行跳转
    navigation.navigate('TabsLayout')

	return (
		<View>
            {/* FormChecked 组件中要用到,需要传navigation过去 */}
			<FormChecked navigation={navigation} />
		</View>
	);
}

2. 在 html 中使用,示例:

export const Login = ({navigation}:any) => {
  
  return (
    <View>
      <View>
        <Button
          title="Go to Login"
          onPress={() => navigation.navigate('TabsLayout')}
        />
      </View>
    </View>
  );
}

带 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 (
    <Tab.Navigator
      initialRouteName="Home"
      screenOptions={{
        tabBarActiveTintColor: '#2089DC', // 底部导航栏 选中时的颜色
      }}
    >
      <Tab.Screen
        name="Home"
        component={Home}
        options={{
          title: "首页",
          headerShown: false, // 隐藏标题栏
          tabBarLabel: '首页',
          tabBarIcon: ({ color, size }) => (
            <Cloud stroke={color} width={size} height={size} />
          ),
        }}
      />      
      <Tab.Screen
        name="Settings"
        component={Settings}
        options={{ 
          title: '我的',
          headerShown: false, // 隐藏标题栏
          tabBarLabel: '我的',
          tabBarIcon: ({ color, size }) => (
            <User stroke={color} width={size} height={size} />
          ),
        }}
      />
    </Tab.Navigator>
  );
}

注意

1. 这里必须要把 NavigationContainer 作为根组件,否则不生效

// 错误的写法, 这里路由就没有生效
<View>
    <Text>测试项目11</Text>
    <NavigationContainer>
        <Navigator initialRouteName="Home">
            <Screen name="Home" component={Home} />
            <Screen name="About" component={About} />
        </Navigator>
    </NavigationContainer>
</View>

// 正确的写法
<NavigationContainer>
     <Text>测试项目11</Text>
     <Navigator initialRouteName="Home">
        <Screen name="Home" component={Home} />
        <Screen name="About" component={About} />
     </Navigator>
</NavigationContainer>

 2. Screen 组件用来定义路由:路由配置、取名、渲染

3. 这里的 initialRouteName默认显示的页面,可以理解为首页

重置导航堆栈

退出登录的时候重置导航堆栈,解决React Navigation对屏幕的缓存会保留上一个屏幕的状态和参数,导致重新登录会进入退出前的最后一个画面的问题。

navigation.reset({
  index: 0,
  routes: [{ name: 'Login' }],
})

Navigation 方法总结

常用方法

导航到指定的路由(屏幕)
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: 生命周期事件类型。例如: focusblurbeforeRemove 等等。
  • callback: 将在事件发生时调用的回调函数。
获取当前屏幕的父导航器的导航对象 
dangerouslyGetParent()
  • 这个方法通常只在嵌套导航中使用。

不常用方法

发送一个动作到导航器中的所有屏幕
dispatch(action)
  • 这个方法通常只在需要处理整个导航器状态的高级场景中使用。
检查当前屏幕是否可以返回到前一个屏幕 
canGoBack()
  • 返回一个布尔值。
发出一个事件到屏幕中的所有监听器 
emit(eventName, data)
  • 你可以通过添加事件监听器来接收这些事件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值