当前位置: 首页 > news >正文

React Navigation 使用导航

在 Web 浏览器中,您可以使用锚标记链接到不同的页面。当用户单击链接时,URL 会被推送到浏览器历史记录堆栈中。当用户按下后退按钮时,浏览器会从历史堆栈顶部弹出该项目,因此活动页面现在是以前访问过的页面。React Native 不像 Web 浏览器那样具有全局历史堆栈的内置概念,而 React Navigation 就是帮助我们实现导航管理的工具。

React Navigation 的堆栈导航器为您的应用程序提供了一种在屏幕之间转换和管理导航历史记录的方法。如果您的应用程序仅使用一个堆栈导航器,那么它在概念上类似于 Web 浏览器处理导航状态的方式 - 当用户与其交互时,您的应用程序会从导航堆栈中推送和弹出项目,这会导致用户看到不同的屏幕。React Navigation 的堆栈导航器提供了您在 Android 和 iOS 上在堆栈中的路由之间导航时所期望的手势和动画。

安装堆栈导航器

在上一篇文章中,我们安装了导航器的构建模块和基础模块,当我们需要堆栈导航器的话则需要安装如下包:

npm install @react-navigation/native-stack

创建堆栈

首先我们先来看一个简单的实例:

import React from "react";
import Home from "./page/Home";
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";const App: React.FC = () => {const Stack = createNativeStackNavigator();return (<NavigationContainer><Stack.Navigator><Stack.Screen name="Home Page" component={Home} /></Stack.Navigator></NavigationContainer>);
};export default App;

运行后效果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uDUJWkBl-1693035587956)(./images/ReactNavigation.png “ReactNavigation1”)]

从上述的例子我们可以看到我们使用了一个createNativeStackNavigator()方法来创建导航堆栈。createNativeStackNavigator是一个返回包含 2 个属性的对象的函数:ScreenNavigator。它们都是用于配置导航器的 React 组件。应该 Navigator 包含 Screen 元素作为其子元素来定义路由的配置。

NavigationContainer 是管理导航树并包含导航状态的组件。该组件必须包装所有导航器结构。通常,我们会在应用程序的根目录渲染此组件,这通常是从 App.tsx 中进行绑定。

配置第二条导航路线

在上述的代码基础上改为如下代码:

<Stack.Navigator initialRouteName="Home"><Stack.Screen name="Home" component={HomeScreen} /><Stack.Screen name="Details" component={DetailsScreen} />
</Stack.Navigator>

现在我们的堆栈有两条路线,一条 Home 路线和一条 Details 路线。可以使用组件来指定路线 Screen。该 Screen 组件接受一个 name 与我们将用于导航的路线名称相对应的 prop,以及一个 component 与它将渲染的组件相对应的 prop。

现在路由导航中,Home 路由对应组件 Home,Details 路由对应组件 DetailsScreen。

注意:
Stack.Screen组件中的component接受组件,而不是渲染函数,不要传递内联函数(例如:component={() => <组件 />}),否则当父组件重新渲染时,您的组件将卸载并重新安装,从而丢失所有状态。请参阅传递额外的 props 以获取替代方案。

Stack.Screen 说明

Stack.Screen组件除了namecomponent属性外,还可以使用options来设置其他参数属性,具体实例如下:

<Stack.Navigator><Stack.Screenname="Home Page"component={Home}options={{ title: "Overview" }}/><Stack.Screen name="Detail Page" component={ReviewDetails} />
</Stack.Navigator>

有时候我们可能想将额外的参数传递给对应的组件,我们有如下两个方式来实现:

  • 使用 React context 并使用 context 提供程序包装导航器以将数据传递到屏幕(推荐)

  • 对屏幕使用渲染回调而不是指定 componentprop:

    <Stack.Screen name="Home">{(props) => <HomeScreen {...props} extraData={someData} />}
    </Stack.Screen>
    

导航切换

首先我们举一个例子:

export default function Home(props: { navigation: any }) {return (<View><Text>Home</Text><Buttontitle="切换到详情页"onPress={() => props.navigation.navigate("Detail Page")}/></View>);
}

实现上述代码后,我们点击按钮后页面会切换到详情页。接下来我们来说明一下具体的参数:

  • navigation

    本机的堆栈导航器对象数据,并且每个组件都会带有此属性

  • navigate(‘Detail Page’)

    调用此函数可以帮我们把页面跳转到对应名称组件的页面

**注意:**如果我们在使用navigation.navigate进行页面跳转的时候,跳转没有定义的路由时,开发环境下会报出对应的错误信息,但是打包的生产环境不会有任何反映。

路由循环

现在我们有两条路由,那么我们再进入详情页后,在重新导航到详情页那么会发生什么,我们用如下的代码实现验证一下:

export default function ReviewDetails(props: { navigation: any }) {return (<View><Text>ReviewDetails</Text><Buttontitle="切换到详情页"onPress={() => props.navigation.navigate("Detail Page")}/></View>);
}

运行上述代码后,你会发现当点击切换到详情页时,不会发生任何操作,并且点击返回后,我们可以直接一次性返回到首页。因为当我们在首页点击切换到详情页后,我们的路由线路会跳转到详情页上,在当我们点击切换到详情页时,程序会判断是否在详情页路由线上,假如在的话就不会做任何操作。

假设我们实际上想要添加一个新的详情页路由时,并且不管现有的导航历史记录如何的情况下,我们可以使用push来实现。具体实例如下:

<View><Text>ReviewDetails</Text><Buttontitle="切换到详情页"onPress={() => props.navigation.push("Detail Page")}/>
</View>

每次您调用时,push 我们都会向导航堆栈添加一条新路线。当您 navigate 第一次调用它时,它会尝试查找具有该名称的现有路由,并且仅在堆栈上还没有路由时才推送新路由。

编程式导航

有时候我们可能会遇到头部导航没有返回按钮的情况,这时我们就可以使用goBack()方法来实现返回上一级路由的功能,具体代码实例如下:

<Button title="返回上一页" onPress={() => props.navigation.goBack()}></Button>

还有就是我们想清除所有路由信息并返回第一个页面,具体代码如下:

<Buttontitle="清除所有堆栈信息返回首页"onPress={() => props.navigation.popToTop()}
></Button>
http://www.lryc.cn/news/144989.html

相关文章:

  • 双指针算法,基础算法实践,基本的算法的思想,双指针算法的实现
  • idea http request无法识别环境变量
  • 性能测试常见的测试指标
  • 并发 04(Callable,CountDownLatch)详细讲解
  • Json路径表达式
  • 【uniapp 上传图片示例】
  • apache2配置文件 Require all granted是什么意思
  • c/c++ 的一些知识
  • Rancher上的应用服务报错:413 Request Entity Too Large
  • 【LeetCode题目详解】第八章 贪心算法 part01 理论基础 455.分发饼干 376. 摆动序列 53. 最大子序和 day31补
  • ssm+vue中国咖啡文化宣传网站源码和论文
  • 基于MATLAB开发AUTOSAR软件应用层Code mapping专题-part 4 Data store标签页介绍
  • 区间型动态规划典型题目:lintcode 476 · 石子归并【中等,免费】lintcode 593 · 石头游戏 II【中等 vip】
  • 4. 池化层相关概念
  • ChatGPT Prompting开发实战(一)
  • VB车辆管理系统SQL设计与实现
  • java 泛型
  • git 查看/配置 local/global 用户名称和用户邮箱
  • 无涯教程-分类算法 - 简介
  • python venv 打包,更换路径后,仍然读取到旧路径 ,最好别换路径,采用docker封装起来
  • MATLAB算法实战应用案例精讲-【自然语言处理】语义分割模型-DeepLabV3
  • road to master
  • <深度学习基础> 激活函数
  • 评价指标BLUE了解
  • 5G网关如何提升智慧乡村农业生产效率
  • 微信小程序分享后真机参数获取不到和部分参数不能获取问题问题解决
  • Confluence使用教程(用户篇)
  • 网络基础知识socket编程
  • 基于SpringBoot的员工(人事)管理系统
  • 【计算机网络】序列化与反序列化