乐趣区

关于前端:reactnavigation606版本使用详解基于RN065版本

命令装置

// 装置根底包 ^6.0.6
yarn add @react-navigation/native -S
// 装置路由包 ^6.2.5
yarn add @react-navigation/native-stack -S

//RN 版本 0.65.1 React 版本 17.0.2
"react": "17.0.2",
"react-native": "0.65.1",

路由配置

包援用

import {NavigationContainer, useNavigation} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
const Stack = createNativeStackNavigator<RootStackParamList>();
const Navigator = Stack.Navigator;
const Screen = Stack.Screen;

路由列表

// 路由页面配置
<NavigationContainer>
    <Stack.Navigator
        initialRouteName={Views.Home}
        screenOptions={{
            headerShadowVisible: false, // android 导航去暗影
            headerTitleAlign: 'center', // 题目居中
            // 设置导航栏字体款式
            headerTitleStyle: {
                fontSize: 17,
                color: '#333333',
                fontFamily: 'PingFangSC-Semibold',
                fontWeight: '700',
            },
            headerLeft: () => headerLeft(),
        }}
    >
        <Stack.Screen
            name={Views.Home}
            component={Home}
            options={{title: '每日工作'}}
        />
        <Stack.Screen
            name={Views.NewTask}
            component={NewTask}
            options={{title: '老手工作'}}
        />
        <Stack.Screen
            name={Views.Redeem}
            component={Redeem}
            options={{title: '积分兑换'}}
        />
        <Stack.Screen
            name={Views.Rule}
            component={Rule}
            options={{title: '积分兑换规定'}}
        />
    </Stack.Navigator>
</NavigationContainer>

属性参数详解

Stack.Navigator

导航全局配置,再次配置的参数在所有路由页面的导航下面全副失效,具体属性如下

initialRouteName: // 指定路由首页 类比 React 的跟路由页面
// 用于导航器中屏幕的默认选项
screenOptions: {
    headerShadowVisible: false, // android 导航去暗影 默认 true 开启状态
    headerTitleAlign: 'center', // 题目居中 默认 'left'
    headerTitle: '题目', // 全局题目 在此设置是不失效的 默认展现路由页面的 name
    // 设置导航栏字体款式
    headerTitleStyle: {
        fontSize: 17,
        color: '#333333',
        fontFamily: 'PingFangSC-Semibold',
        fontWeight: '700',
    },
    headerTintColor: 'red', // 导航栏字体色彩设置 如果设置了 headerTitleStyle 则此处设置不失效
    statusBarStyle: 'light' //"inverted" | "auto" | "light" | "dark" | undefined 状态栏配置
    headerLeft: React.ReactNode, // 导航左侧区域按钮配置 不配置默认展现左箭头返回图标
    headerRight: React.ReactNode // 导航右侧区域配置 默认无
}

以上根底配置基本上能满足绝大多数业务的日常开发了

Stack.Screen

页面导航配置,此处的配置会笼罩全局配置,具体属性参数如下:

const Home = lazy(() => import('./views/home'));
name= 'Home' // 指定的路由页面的名称 必填属性
component= Home // 路由 React 页面挂载 必填属性
initialParams={{itemId: 42}} // 页面初始化参数
// 路由页面导航配置 此处的配置会笼罩全局的 screenOptions
options={{ 
  title: '积分兑换规定', // 路由页面题目 
  headerLeft: React.ReactNode, // 导航左侧区域按钮配置 不配置默认展现左箭头返回图标
  headerRight: React.ReactNode // 导航右侧区域配置 默认无
}}

路由应用

因为新版本的 RN 基本上都采纳 Hooks+TypeScript 的形式来开发,在应用时好多都须要做类型申明

申明文件

首先增加一个全局申明文件,不便前面的自定义 hooks(上面会具体介绍)的调用;

自己的工程开发目录如下:

首先在 types 上面加一个全局的 ts 申明文件 index.ts 内容如下:

import {RouteProp} from '@react-navigation/native'; // 获取 route 的 props
// 枚举进去所有的路由页面的 Name
export enum Views {
    Home = 'Home',
    NewTask = 'NewTask',
    Redeem = 'Redeem',
    Rule = 'Rule',
}
interface NewTaskProps {
    title: string;
    action: string;
    funcName: string;
    params: any;
}
// 定义每个路由页面须要传达到下个页面的参数 在目标页面外面申明要承受的参数
export type RootStackParamList = {[Views.Home]: undefined;

    [Views.NewTask]:
        | {
              /** @description 申明往子组件外面的传参 */
              item: NewTaskProps;
              callback: () => void;}
        | undefined;
    [Views.Redeem]:
        | {/** @description 监听页面返回回调父页面 */ callback: () => void;
          }
        | undefined;
    [Views.Rule]: undefined;
};
// 定义申明每个子路由界面接管的具体数据类型 useRoute 前面详解应用
export type RootRouteType = RouteProp<RootStackParamList>;
// This registers which makes navigation fully type-safe.
// https://reactnavigation.org/docs/typescript#specifying-default-types-for-usenavigation-link-ref-etc
// 全局申明 useNavigation 自定义 hooks 办法的参数
declare global {
    namespace ReactNavigation {interface RootParamList extends RootStackParamList {}
    }
}

自定义 hooks

目前 react-navigation 提供了自定义 hooks 办法 useNavigation、useRoute 等,重点解说一下路由的应用

useNavigation

1、返回监听 navigation.goBack()

import {useNavigation} from '@react-navigation/native';

// 左侧返回按钮
const headerLeft = () => {
    // hooks 外面获取导航器对象
    const navigation = useNavigation();
    return (
        <TouchableOpacity
            onPress={() => {
                // 如果无奈在应用路由退出后 调用 native 协定敞开以后 RN 容器
                navigation.canGoBack() ? navigation.goBack() : Alert.alert('路由首页');
            }}
        >
            <Image
                style={{
                    height: 25,
                    width: 25,
                }}
                source={require('./images/back.png')}
            />
        </TouchableOpacity>
    );
};

2、路由跳转 navigation.navigate

import React, {FC} from 'react';
import {useNavigation} from '@react-navigation/native';
import {Views} from '@types'; // 此处配置了 alias 能够间接应用 @
const Home: FC = () => {
  // 自定义 hooks 外面调用导航对象
    const navigation = useNavigation();
  // 一般不带参数跳转
  const jumpNewTask = () => {
    // 不带参数的一般跳转 如果没有全局的 ReactNavigation 申明 按文档调用会报如下谬误一的问题
    navigation.navigate(Views.NewTask); 
  }
  // 带参数跳转
  const jumpNewTask = () => {
    // 如果不再目标页面做入参的申明会有如下报错(谬误二)navigation.navigate(Views.NewTask, {
            item: {
                title: '弹窗',
                action: 'CSTShowDialog',
                funcName: 'dialog',
                params: {
                    title: '舒适提醒',
                    content: '请上传证件照,否则发帖须要扣费 10 元',
                    btns: [{ color: '#ff552e', text: '确定'},
                        {color: '#000000', text: '勾销'},
                    ],
                },
            },
            callback: () => {
                // 老手工作返回首页 拉取积分信息
                getTaskInfo();},
        }); 
  }
}

报错一

报错二

3、重写导航 navigation.setOptions

import React, {FC, useLayoutEffect, useEffect} from 'react';
import {View, Text, TouchableOpacity} from 'react-native';
import {useNavigation, useRoute} from '@react-navigation/native'
const Redeem: FC = () => {const navigation = useNavigation();
    const headerRight = () => {
        return (
            <TouchableOpacity
                onPress={() => {navigation.navigate(Views.Rule);
                }}
            >
                <Text style={styles.headerRight}> 兑换规定 </Text>
            </TouchableOpacity>
        );
    };
    useLayoutEffect(() => {
        navigation.setOptions({headerRight: () => headerRight(),});
    }, []);
}

4、路由页面内赋值参数 navigation.setParams

import React, {FC, useLayoutEffect} from 'react';
import {View, Text} from 'react-native';
import {useNavigation} from '@react-navigation/native';
const NewTask: FC = () => {const navigation = useNavigation();
  useLayoutEffect(() => {
        // 初始化赋值
        navigation.setParams({testParam: 'test'});
    }, []);
}
export default NewTask;
// 页面内赋值个别要应用?: 可选参数的形式申明 否则上个页面的路由跳转会报如下谬误
// 谬误申明
[Views.NewTask]:
        | {
              /** @description 申明往子组件外面的传参 */
              item: NewTaskProps;
              testParam: string;
              callback: () => void;}
        | undefined;
// 正确的申明形式
[Views.NewTask]:
        | {
              /** @description 申明往子组件外面的传参 */
              item: NewTaskProps;
              testParam?: string;
              callback: () => void;}
        | undefined;

5、其余

其余 API 暂不做详解

useRoute

路由页面参数接管自定义 hooks

1、路由参数接管 route.params

import React, {FC, useLayoutEffect} from 'react';
import {View, Text} from 'react-native';
import {useNavigation, useRoute} from '@react-navigation/native';
import {RootRouteType} from '@types';
const NewTask: FC = () => {const navigation = useNavigation();
  // @react-navigation/native 自定义 hooks 外面获取路由参数对象
  // 谬误 未声明间接应用报错如下 图一
  // const route = useRoute();
  // 正确应用形式 先申明后应用 RootRouteType 如上 types 外面的申明
  const route = useRoute<RootRouteType>();
  useLayoutEffect(() => {
        // 初始化赋值
        navigation.setParams({testParam: 'test'});
        // 路由返回时触发调用父页面传入的 callback 办法,模仿路由回调
            return () => {route.params?.callback();
        };
    }, []);
  // 路由参数获取 
  const getParams = () => {
        // 页面获取到的路由参数如下:(图二所示)有父页面路由跳转的传参,有本页面类本人注册的路由页面参数 testParam
        const params = route.params;
        console.log(params);
    };
}
export default NewTask;

图一

图二

2、其余

总结

以上是自己业务开发中罕用的性能总结,有更深层次的应用,欢送留言;总结不易,转载请赋原文链接。

退出移动版