命令装置
// 装置根底包 ^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、其余
总结
以上是自己业务开发中罕用的性能总结,有更深层次的应用,欢送留言;总结不易,转载请赋原文链接。