介绍
React Navigation 是一个流行的库,用于在 React Native 应用程序中进行路由和导航。
该库有助于解决在多个屏幕之间导航和在它们之间共享数据的问题。
在本教程结束时,您将拥有一个基本的社交网络。 它将显示用户拥有的连接数,并提供一种与其他朋友联系的方式。 您将使用此示例应用程序来探索如何使用 react-navigation 浏览移动应用程序屏幕。
先决条件
要完成本教程,您需要:
- Node.js 的本地开发环境。 关注【X7X】如何安装Node.js并创建本地开发环境【X76X】。
- 熟悉设置环境以创建新的 React Native 项目并使用 iOS 或 Android 模拟器可能会有所帮助。
本教程已使用 Node v14.7.0、npm v6.14.7、react v16.13.1、react-native v0.63.2、@react-navigation/native v5.7.3、和 @react-navigation/stack v5.9.0。
第 1 步——创建一个新的 React Native 应用程序
首先,通过在终端中输入以下命令来创建一个新的 React Native 应用程序:
npx react-native init MySocialNetwork --version 0.63.2
然后,导航到新目录:
cd MySocialNetwork
并启动 iOS 应用程序:
npm run ios
或者,对于 Android:
npm run android
注意:如果遇到任何问题,可能需要参考 React Native CLI疑难解答问题。
这将为您创建一个骨架项目。 它现在看起来不像社交网络。 让我们解决这个问题。
打开App.js:
nano App.js
将 App.js 的内容替换为以下代码以显示欢迎消息:
应用程序.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
class App extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Welcome to MySocialNetwork!</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
export default App;
保存文件。 现在,当您运行应用程序时,一个 Welcome to MySocialNetwork! 消息将出现在您的模拟器中。
在下一步中,您将向应用程序添加更多屏幕。
第 2 步 — 创建 HomeScreen 和 FriendsScreen
目前,您只有一个屏幕显示欢迎消息。 在此步骤中,您将为您的应用程序创建两个屏幕:HomeScreen 和 FriendsScreen。
HomeScreen
您的应用将需要 HomeScreen。 HomeScreen 将显示您网络中已有的朋友数量。
从 App.js 中获取代码并将其添加到一个名为 HomeScreen.js 的新文件中:
cp App.js HomeScreen.js
打开HomeScreen.js:
nano HomeScreen.js
修改 HomeScreen.js 以使用 HomeScreen 而不是 App:
HomeScreen.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
class HomeScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>You have (undefined) friends.</Text>
</View>
);
}
}
// ...
export default HomeScreen;
此代码将生成 You have (undefined) friends. 占位符消息。 您稍后将提供一个值。
FriendsScreen
您的应用还需要 FriendsScreen。 在 FriendsScreen 上您将能够添加新朋友。
从 App.js 中获取代码并将其添加到一个名为 FriendsScreen.js 的新文件中:
cp App.js FriendsScreen.js
打开FriendsScreen.js:
nano FriendsScreen.js
修改 FriendsScreen.js 以使用 FriendsScreen 而不是 App:
FriendsScreen.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
class FriendsScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Add friends here!</Text>
</View>
);
}
}
// ...
export default FriendsScreen;
此代码将生成 Add friends here! 消息。
此时,您有 HomeScreen 和 FriendsScreen。 但是,没有办法在它们之间导航。 您将在下一步中构建此功能。
为了在屏幕之间导航,您将使用 StackNavigator。 StackNavigator 的工作方式与 调用堆栈 完全相同。 您导航到的每个屏幕都被推到堆栈的顶部。 每次您点击后退按钮时,屏幕都会从堆栈顶部弹出。
首先,安装@react-navigation/native:
npm install @react-navigation/native@5.7.3
然后,安装 @react-navigation/stack 及其对等依赖项:
npm install @react-navigation/stack@5.9.0 @react-native-community/masked-view@0.1.10 react-native-screens@2.10.1 react-native-safe-area-context@3.1.4 react-native-gesture-handler@1.7.0
注意:如果你是为iOS开发,你可能需要导航到ios目录并运行pod install。
接下来,重新访问 App.js:
nano App.js
将 NavigationContainer 和 createStackNavigator 添加到 App.js:
应用程序.js
import 'react-native-gesture-handler';
import React from 'react';
import { StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
const Stack = createStackNavigator();
然后,替换render的内容:
应用程序.js
// ...
class App extends React.Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator>
</Stack.Navigator>
</NavigationContainer>
);
}
}
// ...
嵌套在 <Stack.Navigator> 中,添加 HomeScreen:
应用程序.js
import 'react-native-gesture-handler';
import React from 'react';
import { StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import HomeScreen from './HomeScreen';
const Stack = createStackNavigator();
class App extends React.Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
}
// ...
此代码为您的导航器创建了一个非常小的堆栈,只有一个屏幕:HomeScreen。
嵌套在 <Stack.Navigator> 中,添加 FriendsScreen:
应用程序.js
import 'react-native-gesture-handler';
import React from 'react';
import { StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import HomeScreen from './HomeScreen';
import FriendsScreen from './FriendsScreen';
const Stack = createStackNavigator();
class App extends React.Component {
render() {
return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={HomeScreen}
/>
<Stack.Screen
name="Friends"
component={FriendsScreen}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
}
// ...
此代码将 FriendsScreen 添加到导航器。
注意: 这与以前版本的 React Navigation 中使用 createStackNavigator 的方式不同。
现在,导航器知道您的两个屏幕。
为 HomeScreen 和 FriendsScreen 添加按钮
最后,添加按钮以将您带到两个屏幕之间。
在 HomeScreen.js 中,添加以下代码:
HomeScreen.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
class HomeScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>You have (undefined) friends.</Text>
<Button
title="Add some friends"
onPress={() =>
this.props.navigation.navigate('Friends')
}
/>
</View>
);
}
}
// ...
在 FriendsScreen.js 中,添加以下代码:
FriendsScreen.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
class FriendsScreen extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Add friends here!</Text>
<Button
title="Back to home"
onPress={() =>
this.props.navigation.navigate('Home')
}
/>
</View>
);
}
}
// ...
再说说this.props.navigation。 只要您的屏幕包含在 StackNavigator 中,它就会自动从 navigation 对象继承许多有用的道具。 在这种情况下,您使用 navigate 移动到不同的页面。
如果您现在打开模拟器,您可以在 HomeScreen 和 FriendsScreen 之间导航。
第 4 步 — 使用 Context 将数据传递到其他屏幕
在这一步中,您将创建一个可能的朋友数组 - Alice、Bob 和 Sammy - 以及一个当前朋友的空数组。 您还将为用户创建将可能的朋友添加到他们当前朋友的功能。
打开App.js:
nano App.js
将 possibleFriends 和 currentFriends 添加到组件的状态:
应用程序.js
// ...
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
possibleFriends: [
'Alice',
'Bob',
'Sammy',
],
currentFriends: [],
}
}
// ...
}
// ...
接下来,添加一个函数将可能的朋友移动到当前朋友列表中:
应用程序.js
// ...
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
possibleFriends: [
'Alice',
'Bob',
'Sammy',
],
currentFriends: [],
}
}
addFriend = (index) => {
const {
currentFriends,
possibleFriends,
} = this.state
// Pull friend out of possibleFriends
const addedFriend = possibleFriends.splice(index, 1)
// And put friend in currentFriends
currentFriends.push(addedFriend)
// Finally, update the app state
this.setState({
currentFriends,
possibleFriends,
})
}
// ...
}
// ...
至此,您已经完成了添加朋友的功能。
将 FriendsContext 添加到 App
现在您可以在 App.js 中添加朋友,但您需要将他们添加到 FriendsScreen.js 并让他们显示在 HomeScreen.js 中。 由于该项目是使用 React 构建的,因此您可以使用上下文将此功能注入到您的屏幕中。
注意: 在之前的 React Navigation 版本中,可以使用 screenProps 在屏幕之间共享数据。 在当前版本的 React Navigation 中,推荐使用 React Context 在屏幕之间共享数据。
为避免循环引用,您将需要一个新的 FriendsContext 文件:
nano FriendsContext.js
导出 FriendsContext:
FriendsContext
import React from 'react'; export const FriendsContext = React.createContext();
打开App.js:
nano App.js
添加FriendsContext:
应用程序.js
import 'react-native-gesture-handler';
import React from 'react';
import { StyleSheet } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { FriendsContext } from './FriendsContext';
import Home from './Home';
import Friends from './Friends';
const Stack = createStackNavigator();
class App extends React.Component {
// ...
render() {
return (
<FriendsContext.Provider>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={Home}
/>
<Stack.Screen
name="Friends"
component={Friends}
/>
</Stack.Navigator>
</NavigationContainer>
</FriendsContext.Provider>
);
}
}
// ...
此代码将 FriendsContext 建立为新的 Context 对象 并将 NavigationContainer 包装在 Context.Provider 组件中,因此组件树中的任何子级都可以订阅上下文更改.
由于您不再使用 View 或 Text,因此可以从 react-native 中删除这些导入。
您需要提供 value 以使消费者可以访问数据:
应用程序.js
// ...
class App extends React.Component {
// ...
render() {
return (
<FriendsContext.Provider
value={
{
currentFriends: this.state.currentFriends,
possibleFriends: this.state.possibleFriends,
addFriend: this.addFriend
}
}
>
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen
name="Home"
component={Home}
/>
<Stack.Screen
name="Friends"
component={Friends}
/>
</Stack.Navigator>
</NavigationContainer>
</FriendsContext.Provider>
);
}
}
// ...
这将允许 HomeScreen 和 FriendsScreen 引用对 currentFriends 和 possibleFriends 的任何上下文更改。
现在您可以在屏幕中引用上下文。
将 FriendsContext 添加到 HomeScreen
在此步骤中,您将设置应用程序以显示当前好友数。
打开HomeScreen.js:
nano HomeScreen.js
并添加 FriendsContext:
HomeScreen.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { FriendsContext } from './FriendsContext';
class HomeScreen extends React.Component {
// ...
}
HomeScreen.contextType = FriendsContext;
// ...
这段代码建立了一个 Class.contextType。 您现在可以在屏幕中访问上下文。
例如,让我们让您的 HomeScreen 显示您有多少 currentFriends:
HomeScreen.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { FriendsContext } from './FriendsContext';
class Home extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>You have { this.context.currentFriends.length } friends!</Text>
<Button
title="Add some friends"
onPress={() =>
this.props.navigation.navigate('Friends')
}
/>
</View>
);
}
}
HomeScreen.contextType = FriendsContext;
// ...
如果您在模拟器中再次打开您的应用并查看 HomeScreen,您将看到消息:您有 0 个朋友!。
将 FriendsContext 添加到 FriendsScreen
在此步骤中,您将设置应用程序以显示可能的朋友并提供将他们添加到当前朋友的按钮。
接下来,打开FriendsScreen.js:
nano FriendsScreen.js
并添加 FriendsContext:
FriendsScreen.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { FriendsContext } from './FriendsContext';
class FriendsScreen extends React.Component {
// ...
}
FriendsScreen.contextType = FriendsContext;
// ...
此代码建立 Class.contextType。
现在,在 FriendsScreen.js 中创建一个添加好友的按钮:
FriendsScreen.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import { FriendsContext } from './FriendsContext';
class Friends extends React.Component {
render() {
return (
<View style={styles.container}>
<Text>Add friends here!</Text>
{
this.context.possibleFriends.map((friend, index) => (
<Button
key={ friend }
title={ `Add ${ friend }` }
onPress={() =>
this.context.addFriend(index)
}
/>
))
}
<Button
title="Back to home"
onPress={() =>
this.props.navigation.navigate('Home')
}
/>
</View>
);
}
}
FriendsScreen.contextType = FriendsContext;
// ...
如果您在模拟器中再次打开您的应用并查看 FriendsScreen,您将看到要添加的好友列表。
如果您访问FriendsScreen并点击按钮添加好友,您会看到possibleFriends列表减少。 如果您访问HomeScreen,您会看到好友数量增加。
您现在可以在屏幕之间导航并在它们之间共享数据。
结论
在本教程中,您创建了一个具有多个屏幕的示例 React Native 应用程序。 使用 React Navigation,您设计了一种在屏幕之间导航的方法。 使用 React Context,您开发了一种在屏幕之间共享数据的方法。
本教程的完整 源代码可在 GitHub 上获得。
如果你想深入了解 React Navigation,请查看 他们的文档 。
React Navigation 并不是唯一的路由和导航解决方案。 还有 React Native Navigation、React Native Router Flux 和 React Router Native。
如果您想了解有关 React 的更多信息,请查看我们的 如何在 React.js 中编码,或查看 我们的 React 主题页面 以了解练习和编程项目。