共计 11570 个字符,预计需要花费 29 分钟才能阅读完成。
首发于公众号 前端混合开发 ,欢送关注。
挪动应用程序由多个屏幕组成。在构建挪动应用程序时,首要思考的是如何解决用户在应用程序中的导航问题,例如屏幕的展现和屏幕之间的切换。
React Navigation 是 React Native 最驰名的导航库之一。在本教程中,咱们将探讨 React Native 中导航的基础知识,介绍如何开始应用 React Navigation,并通过一些 React Native 导航示例进行解说。
什么是 React Navigation
React Navigation 是一个独立的库,可帮忙咱们在 React 应用程序中实现导航性能。
React Navigation 是用 JavaScript 编写的,并不间接应用 iOS 和 Android 上的原生导航 API。相同,它从新创立了这些 API 的某些子集。这样就能够集成第三方 JS 插件,实现最大水平的自定义,并且更易于调试,而无需学习 Objective-C
、Swift
、Java
、Kotlin
等语言。
什么是 React Native Navigation
React Native Navigation 是一个受欢迎的 React Navigation 代替计划。它是一个依赖于并且被设计用于与 React Native 一起应用的模块。React Native Navigation 有一点不同,它间接应用 iOS 和 Android 上的原生导航 API,这使得它可能提供更加原生的外观和感觉。在撰写本文时,React Native Navigation 的以后稳固版本是 React Navigation 6.1。
另一种抉择:React Router Native
React Router Native 是在 React Native 应用程序中实现导航性能的另一种解决方案。它由 Remix 团队开发。
React Router Native 与 React Router 框架共享大部分 API 代码。这意味着,应用过 React Router 的 Web 开发人员会发现,应用 React Router Native 也很容易。
就易用性而言,React Navigation 和 React Router Native 完全相同。例如,请看上面的 Router Native 代码:
const Home = () => <Text>Home</Text>;
const About = () => <Text>About</Text>;
const App = () => (
<NativeRouter>
<View>
<View>
{/* Define our links. They are like anchor tags */}
<Link to="/">
<Text>Home</Text>
</Link>
<Link to="/about">
<Text>About</Text>
</Link>
</View>
{/*Define our routes for this project*/}
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</View>
{/*The NativeRouter*/}
</NativeRouter>
);
与 Navigation 相比,咱们能够看到代码是类似的:
import {NavigationContainer} from "@react-navigation/native";
import {createNativeStackNavigator} from "@react-navigation/native-stack";
function HomeScreen() {
return (
<View>
<Text>Home Screen</Text>
</View>
);
}
function AboutScreen() {
return (
<View>
<Text>About Screen</Text>
</View>
);
}
const Stack = createNativeStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
{/*Define our routes*/}
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="About" component={AboutScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}
两个库中用于实现路由的代码完全相同。这是一大长处,因为这意味着学习这两个框架的难度都不大。
如果你来自 Web 开发背景,我会举荐应用 React Router Native,因为它的应用形式与 React Router 雷同。否则,应该抉择 React Navigation,因为它领有更大的社区,因而有更多的开发反对。
装置 React Navigation
既然咱们曾经理解了什么是 React Navigation 以及它与 React Router Native 的关系,那么就让咱们看看如何在应用程序中应用它。
注:在本文中,咱们将在 React Native 应用程序中应用 Expo。
首先,咱们应用上面的命令创立一个新的应用程序:
npx create-expo-app ReactNavigationDemo
这将创立一个名为 ReactNavigationDemo
的新我的项目:
接下来,cd 进入我的项目文件夹,关上代码编辑器:
cd ReactNavigationDemo
如果应用的是 VS Code,则能够应用此性能在编辑器中关上以后文件夹:
code .
用这个启动应用程序:
npx expo start
接下来,应用以下任一命令在 React Native 我的项目中装置 React Navigation 库:
/* npm */
npm install @react-navigation/native
/* yarn */
yarn add @react-navigation/native
咱们还须要装置一些依赖项,即 react-native-screens
和 react-native-safe-area-context
:
如果你留神到了,咱们没有应用 npm
或 yarn
装置这些依赖项。相同,咱们应用了 npx expo install
,因为它会装置与咱们的我的项目软件包兼容的依赖版本。
我建议您始终应用该命令来装置依赖包,因为 npm 和 yarn 将始终装置最新版本,而最新版本可能与您的我的项目不兼容。毛病是可能会呈现生产级别的谬误。
React Native 堆栈导航器
React Navigation 应用 JavaScript 构建,让咱们创立的组件和导航模式在外观和感觉上都与真正的原生模式无异。
React Navigation 提供了一个基于堆栈的导航模型,容许屏幕被推入和弹出导航堆栈。通过堆栈导航,你能够应用一个堆栈导航器来定义你的应用程序的导航构造,该导航器保护着一个屏幕堆栈。任何给定工夫只有一个屏幕出现给用户,每个屏幕在被推入堆栈时显示,即当用户导航到某个屏幕时,它就被推到堆栈的顶部。
设想一堆纸张。导航到一个新屏幕会将其放在堆栈的顶部,而导航回去则会将其从堆栈中移除。堆栈导航器还提供了相似于原生 iOS 和 Android 的过渡成果和手势。
留神,一个应用程序能够有多个堆栈导航器。
了解堆栈导航器与原生堆栈导航器的区别
在 React Native 中,咱们有两个堆栈导航库:@react-navigation/stack
和 @react-navigation/native-stack
。这两个库都提供了基于堆栈的导航模型,便于在屏幕之间进行转换,将每个新屏幕放在堆栈的顶部。
然而,默认状况下,尽管 @react-navigation/stack
被配置为具备相熟的 iOS 和 Android 外观和感觉,并且能够自定义动画,但 @react-navigation/native-stack
则利用了原生 API;iOS 上的 UINavigationController
和 Android 上的 Fragment,这样导航的行为就会与原生构建的应用程序一样。
为了了解这两个库之间的区别,让咱们从以下几个关键因素来看看它们:
- 定制性 :依据你的需要,
@react-navigation/native-stack
可能不如@react-navigation/stack
可定制。所以,如果你须要依据本人的感觉定制导航动画,@react-navigation/stack
应该是你的首选。 - 性能 :
@react-navigation/native-stack
提供了更好的性能。与@react-navigation/stack
相比,它应用本地堆栈 View 组件来渲染屏幕,使过渡动画更快、更好、更晦涩。 - 兼容性 :两个库都与 React Navigation 兼容。
@react-navigation/native-stack
还通过react-native-web
提供了对 Web 的根本反对。另一方面,@react-navigation/stack
则没有。你还必须装置react-native-gesture-handler
并在入口或根文件(index.js 或 App.js)的顶部导入它。跳过这一步通常会导致生产级别的解体,即便在开发中工作失常。此外,如果你想要应用 UIkit 格调来动画化你的头部,你将须要装置一个额定的包:@react-native-masked-view/masked-view
。
React Native 导航器 React Native
在本节中,咱们将探讨 React Native 导航中的不同导航器,以及如何应用 React Navigation 库实现它们。
1. 应用堆栈导航器在屏幕组件之间导航
首先,咱们创立两个文件,即 Homescreen
和 Aboutscreen
:
/* components/Homescreen.js */
import React from "react";
import {Button, View, Text} from "react-native";
export default function HomeScreen({navigation}) {
return (<View style={{ flex: 1, alignItems: "center", justifyContent: "center"}}>
<Text>Home Screen</Text>
<Button
title="Go to About"
onPress={() => navigation.navigate("About")}
/>
</View>
);
}
请留神下面按钮的 onPress
属性 —— 咱们稍后会解释它的作用:
/* components/Aboutscreen.js */
import React, {Component} from "react";
import {Button, View, Text} from "react-native";
export default function AboutScreen() {
return (<View style={{ flex: 1, alignItems: "center", justifyContent: "center"}}>
<Text>About Screen</Text>
</View>
);
}
我的项目文件夹应该是这样的:
咱们对 App.js
也进行一些批改。在这里,咱们必须进行以下导入:
//tell React that we will implement a navigator
import {NavigationContainer} from "@react-navigation/native";
//create a stack navigator
import {createNativeStackNavigator} from "@react-navigation/native-stack";
在根 App.js 文件中实现导航十分有用,因为从 App.js 导出的组件是 React Native 应用程序的入口点(或根组件),而其余每个组件都是其后辈。
正如你所看到的,咱们将在导航性能中封装所有其余组件:
/* App.js */
import {NavigationContainer} from '@react-navigation/native';
import {createNativeStackNavigator} from '@react-navigation/native-stack';
import HomeScreen from './components/HomeScreen';
import AboutScreen from './components/AboutScreen';
const Stack = createNativeStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
/>
<Stack.Screen
name="About"
component={AboutScreen}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
在下面的代码中,createNativeStackNavigator
为咱们的应用程序提供了一种在屏幕之间过渡的形式,其中每个新屏幕都位于堆栈的顶部。咱们将其配置为相熟的 iOS 和 Android 外观和感觉:在 iOS 中,新屏幕从右侧滑入,而在 Android 中,新屏幕从底部淡入。
在这里,咱们执行了 createNativeStackNavigator
函数,并将其实例存储在 Stack 变量中。稍后,咱们将应用 Stack.Screen
标记传递路由。Home
路由对应于 HomeScreen
,而 About
路由对应于 AboutScreen
。
此外,Stack
会按程序显示,例如,HomeScreen 默认首先显示,因为它位于 Stack 的最上方。要笼罩这一默认选项,能够指定初始门路。请参阅上面的代码:
/* App.js */
// imports....
const Stack = createNativeStackNavigator();
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName='About'>
<Stack.Screen
name="Home"
component={HomeScreen}
/>
<Stack.Screen
name="About"
component={AboutScreen}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
在幕后,createStackNavigator
函数为 HomeScreen 和 AboutScreen 组件提供了一个 navigate
属性。
这个属性容许导航到指定的屏幕组件。这就是为什么咱们能够在 HomeScreen.js
上的一个按钮上应用它,当按下时,会导致页面跳转到 AboutScreen,如下所示:
<Button title="Go to About" onPress={() => navigation.navigate("About")} />;
在 App.js 代码中,咱们将组件封装在 NavigationContainer
组件中,最终创立了一个应用程序容器。该组件治理导航树并蕴含导航状态。
最初,运行应用程序
npx expo start
2. 应用 TabNavigator
大多数挪动应用程序都有一个以上的屏幕。在此类挪动应用程序中,常见的导航形式是基于标签的导航。React Navigation 有一个名为 createBottomTabNavigator
的组件能够帮忙咱们实现这一点。
在实现基于标签的导航之前,应用以下任一命令装置 bottom-tabs
模块:
/* npm */
npm install @react-navigation/bottom-tabs
/* yarn */
yarn add @react-navigation/bottom-tabs
咱们创立一个 ContactScreen
文件,在应用程序中增加另一个屏幕:
/* components/ContactScreen.js */
import React, {Component} from "react";
import {Button, View, Text} from "react-native";
export default function ContactScreen() {
return (<View style={{ flex: 1, alignItems: "center", justifyContent: "center"}}>
<Text>Contact Screen</Text>
</View>
);
}
接下来,咱们将其导入 App.js
文件:
import ContactScreen from './components/ContactScreen';
咱们还将在咱们的 App.js
文件中实现咱们的标签导航。这是因为倡议咱们在根文件中实现所有的导航配置,因为这些配置包裹了所有的导航构造,并将咱们的屏幕作为子元素渲染。
咱们用这行代码替换 createNativeStackNavigator
行:
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
咱们的堆栈导航器也将发生变化。App.js 应该是这样的:
/* App.js */
import {NavigationContainer} from '@react-navigation/native';
import {createBottomTabNavigator} from '@react-navigation/bottom-tabs';
import ContactScreen from './components/ContactScreen';
import HomeScreen from './components/HomeScreen';
import AboutScreen from './components/AboutScreen';
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator initialRouteName="Home">
<Tab.Screen
name="Home"
component={HomeScreen}
/>
<Tab.Screen
name="About"
component={AboutScreen}
/>
<Tab.Screen
name="Contact"
component={ContactScreen}
/>
</Tab.Navigator>
</NavigationContainer>
);
}
运行应用程序,它将看起来像这样:
应用抽屉导航器
要应用抽屉导航,请首先应用以下任一命令装置 @react-navigation/drawer
包:
接下来,咱们将应用 npx expo install 装置依赖项:
npx expo install react-native-gesture-handler react-native-reanimated
接下来,转到 Reanimated 文档中设置我的项目中的手势管制。实现这一步后,在你的 App.js 的顶部导入手势处理器包:
import "react-native-gesture-handler";
咱们还要用抽屉导航更新导航器。复制并用上面的代码替换 App.js 代码:
/* App.js */
import 'react-native-gesture-handler';
import {NavigationContainer} from '@react-navigation/native';
import {createDrawerNavigator} from '@react-navigation/drawer';
import ContactScreen from './components/ContactScreen';
import HomeScreen from './components/HomeScreen';
import AboutScreen from './components/AboutScreen';
const Drawer = createDrawerNavigator();
export default function App() {
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen
name="Home"
component={HomeScreen}
/>
<Drawer.Screen
name="About"
component={AboutScreen}
/>
<Drawer.Screen
name="Contact"
component={ContactScreen}
/>
</Drawer.Navigator>
</NavigationContainer>
);
}
运行应用程序查看后果:
你能够通过在路由名称旁边增加图标来自定义你的抽屉导航。咱们的图标搁置在咱们的资源文件夹内:
咱们能够通过在以下屏幕组件文件中增加 navigationOptions
来进行自定义:
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen
name="Home"
component={HomeScreen}
options={{ //change the configuration of our screen
drawerIcon: ({color, number, focused}) => { //set the icon:
return ( //the icon will be an image
<Image
source={require("../assets/home-icon.png")}
style={{height: 30, width: 30}}
/>
);
},
}}
/>
<Drawer.Screen
name="About"
component={AboutScreen}
options={{drawerIcon: ({ color, number, focused}) => { //set the icon for all screens
return (
<Image
source={require("../assets/about-icon.png")}
style={{height: 30, width: 30}}
/>
);
},
}}
/>
<Drawer.Screen
name="Contact"
component={ContactScreen}
options={{drawerIcon: ({ color, number, focused}) => {
return (
<Image
source={require("../assets/contact-icon.png")}
style={{height: 30, width: 30}}
/>
);
},
}}
/>
</Drawer.Navigator>
</NavigationContainer>
drawerActiveTintColor
属性容许你依据导航标签和标签的激活或非激活状态利用任何色彩。例如,咱们能够更改咱们导航抽屉标签的激活状态色彩。转到 Drawer.Navigator
变量,并增加到 options
对象中:
<Drawer.Navigator
initialRouteName="Home"
screenOptions={{drawerActiveTintColor: "#e91e63"}}
>
//... further code.
这就导致了色彩的变动:
4. 应用 useNavigation() 钩子
React Navigation 还提供了一个名为 useNavigation
的 Hook。这个 Hook 使函数组件可能拜访导航对象,并容许它们以编程形式触发导航操作。当你无奈间接将导航属性传递给组件时,它十分有用。
诚实说,我更常常应用 Hook,因为它更容易在我的性能组件中进行治理,而且应用起来也十分不便。
在你的 HomeScreen
文件中,用上面的代码替换你的代码:
/* components/HomeScreen.js */
import React from 'react';
import {Button, View, Text} from 'react-native';
import {useNavigation} from '@react-navigation/native';
export default function HomeScreen() {const navigation = useNavigation();
return (
<View
style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}
>
<Text>Home Screen</Text>
<Button
title="Go to About"
onPress={() => navigation.navigate('About')}
/>
</View>
);
}
useNavigation
钩子是从 @react-navigation/native
模块导入的,它会返回一个带有编程操作的导航对象。
在 About 页面中,能够为返回按钮实现雷同的办法。请参阅以下代码:
/* components/About.js */
import React, {Component} from 'react';
import {Button, View, Text} from 'react-native';
import {useNavigation} from '@react-navigation/native';
export default function AboutScreen() {const navigation = useNavigation();
return (
<View
style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}
>
<Text>About Screen</Text>
<Button
title="Go Back"
onPress={() => {navigation.goBack();
}}
/>
</View>
);
}
在 React Navigation 中向屏幕传递参数
向路由传递参数有两个简略的步骤:传递参数,而后在子路由或屏幕中读取参数。
首先,将参数作为 navigation.navigate
函数的第二个参数放入一个对象中,从而将参数传递给路由:
而后,读取屏幕组件中的参数。参数可在 route.params
中找到:
export default function HomeScreen({route, navigation}) {
// 'route' 变量为咱们提供页面信息。// 它还存储参数及其值
const {paramName} = route.params; // 咱们的参数 'paramName' 存储在这里。// .. 后续代码..
}
最初,要设置头部题目,咱们能够像这样应用 options
属性的 title
属性:
<Drawer.Screen
name="Home"
component={HomeScreen}
options={{title: "Home Page", //set the title of the page to 'Home page'}}
/>
总结
还有更多能够做的事件,而 React Navigation 将满足你的大部分需要。要理解更多信息,请查看 React Navigation 文档,并随时从我的 GitHub 仓库中获取最终代码。
交换
首发于公众号 大迁世界,欢送关注。📝 每周一篇实用的前端文章 🛠️ 分享值得关注的开发工具 ❓ 有疑难?我来答复
本文 GitHub https://github.com/qq449245884/xiaozhi 已收录,有一线大厂面试残缺考点、材料以及我的系列文章。