irpas技术客

React Navigation 基本使用_流水吾情_react-navigation使用

大大的周 3007

React Navigation 基本使用

参考资料

https://reactnavigation.org/docs/

环境搭建 Minimum requirementsreact-native >= 0.63.0 expo >= 41 (if you use Expo)typescript >= 4.1.0 (if you use TypeScript) Installation npm install @react-navigation/native npm install react-native-screens react-native-safe-area-context

From React Native 0.60 and higher, linking is automatic. So you don’t need to run react-native link.

If you’re on a Mac and developing for iOS, you need to install the pods (via Cocoapods) to complete the linking.

npx pod-install ios

react-native-screens package requires one additional configuration step to properly work on Android devices. Edit MainActivity.java file which is located in android/app/src/main/java/<your package name>/MainActivity.java.

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(null); }

and make sure to add an import statement at the top of this file:

import android.os.Bundle; Hello React Navigation

React Navigation提供了不同于浏览器的a标签的方案,它提供了适用了IOS和Android合适的过渡动画。

安装原生栈导航库(Installing the native stack navigator library)

到目前为止我们已经安装的库仅仅构建了Navigation的基本快,然而每个Navigation都是有一个自己的库的,为了使用原声的导航栈,我们需要安装@react-navigation/native-stac

npm install @react-navigation/native-stack

@react-navigation/native-stack depends on react-native-screens and the other libraries that we installed in Getting started. If you haven’t installed those yet, head over to that page and follow the installation instructions.

创建一个原生栈导航(Creating a native stack navigator)

createNativeStackNavigator函数会返回一个包含两个属性Screen和Navigator的对象。他们都是用于配置配置navigator的React组件,Navigator应该包含Screen元素作为他们的子元素来为路由定义配置。

NavigationContainer是一个用来管理导航树(navigation tree)的组件并且它包含了 navigation state,这个组件必须包含所有导航的结构,通常的,我们在app的根去渲染这个组件,通常这个组件被App.js被导出。(export)

// In App.js in a new project import * as React from 'react'; import { View, Text } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; function HomeScreen() { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>Home Screen</Text> </View> ); } const Stack = createNativeStackNavigator(); function App() { return ( <NavigationContainer> <Stack.Navigator> <Stack.Screen name="Home" component={HomeScreen} /> </Stack.Navigator> </NavigationContainer> ); } export default App; 基本案例 // In App.js in a new project import * as React from 'react'; import { View, Text, Button } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createNativeStackNavigator } from '@react-navigation/native-stack'; function HomeScreen({navigation}) { return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>Home Screen</Text> <Button title="Go to Details" onPress={() => { navigation.navigate('Details', { itemId: 86, otherParam: 'anything you want here' }) }} /> </View> ); } function DetailsScreen({route,navigation}) { const { itemId, otherParam } = route.params; return ( <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}> <Text>Details Screen</Text> <Text>itemId: {JSON.stringify(itemId)}</Text> <Text>otherParam: {JSON.stringify(otherParam)}</Text> <Button title="Go to Details... again" onPress={() => navigation.push('Details', { itemId: Math.floor(Math.random() * 100), }) } /> <Button title="Go back" onPress={() => navigation.goBack()} /> <Button title="Go back to first screen in stack" onPress={() => navigation.popToTop()} /> </View> ); } const Stack = createNativeStackNavigator(); function App() { return ( <NavigationContainer> <Stack.Navigator initialRouteName="Home"> <Stack.Screen name="Home" component={HomeScreen} options={{ title: '主页' }}/> <Stack.Screen name="Details" component={DetailsScreen} options={{ title: '详情' }}/> </Stack.Navigator> </NavigationContainer> ); } export default App; 携返回值案例 // In App.js in a new project import * as React from "react"; import { View, Text, Button, TextInput } from "react-native"; import { NavigationContainer } from "@react-navigation/native"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; function HomeScreen({ navigation, route }) { React.useEffect(() => { if (route.params?.post) { // Post updated, do something with `route.params.post` // For example, send the post to the server } }, [route.params?.post]); return ( <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}> <Button title="Create post" onPress={() => navigation.navigate("CreatePost")} /> <Text style={{ margin: 10 }}>Post: {route.params?.post}</Text> </View> ); } function CreatePostScreen({ navigation, route }) { const [postText, setPostText] = React.useState(""); return ( <> <TextInput multiline placeholder="What's on your mind?" style={{ height: 200, padding: 10, backgroundColor: "white" }} value={postText} onChangeText={setPostText} /> <Button title="Done" onPress={() => { // Pass and merge params back to home screen navigation.navigate({ name: "Home", params: { post: postText }, merge: true, }); }} /> </> ); } const Stack = createNativeStackNavigator(); function StackScreen() { const screenOptions = { headerStyle: { backgroundColor: "#f4511e", }, headerTintColor: "#fff", headerTitleStyle: { fontWeight: "bold", }, } return ( <Stack.Navigator initialRouteName="Home"> <Stack.Screen name="Home" component={HomeScreen} options={{ title: "主页", ...screenOptions }} /> <Stack.Screen name="CreatePost" component={CreatePostScreen} options={{ title: "创建Post", ...screenOptions }} /> </Stack.Navigator> ); } function App() { return ( <NavigationContainer> <StackScreen /> </NavigationContainer> ); } export default App; Replacing the title with a custom component function LogoTitle() { return ( <Image style={{ width: 50, height: 50 }} source={require('@expo/snack-static/react-native-logo.png')} /> ); } function StackScreen() { return ( <Stack.Navigator> <Stack.Screen name="Home" component={HomeScreen} options={{ headerTitle: (props) => <LogoTitle {...props} /> }} /> </Stack.Navigator> ); } 给标题来点样式 // In App.js in a new project import * as React from "react"; import { View, Text, Button, TextInput } from "react-native"; import { NavigationContainer } from "@react-navigation/native"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; function HomeScreen({ navigation, route }) { React.useEffect(() => { if (route.params?.post) { // Post updated, do something with `route.params.post` // For example, send the post to the server } }, [route.params?.post]); return ( <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}> <Button title="Create post" onPress={() => navigation.navigate("CreatePost")} /> <Text style={{ margin: 10 }}>Post: {route.params?.post}</Text> </View> ); } function CreatePostScreen({ navigation, route }) { const [postText, setPostText] = React.useState(""); return ( <> <TextInput multiline placeholder="What's on your mind?" style={{ height: 200, padding: 10, backgroundColor: "white" }} value={postText} onChangeText={setPostText} /> <Button title="Done" onPress={() => { // Pass and merge params back to home screen navigation.navigate({ name: "Home", params: { post: postText }, merge: true, }); }} /> </> ); } const Stack = createNativeStackNavigator(); function StackScreen() { const screenOptions = { headerStyle: { backgroundColor: "#f4511e", }, headerTintColor: "#fff", headerTitleStyle: { fontWeight: "bold", }, } return ( <Stack.Navigator initialRouteName="Home"> <Stack.Screen name="Home" component={HomeScreen} options={{ headerTitle: () => <Text>Text</Text>, headerRight: () => ( <Button onPress={() => alert('This is a button!')} title="Info" color="black" /> ), }} /> <Stack.Screen name="CreatePost" component={CreatePostScreen} options={{ headerTitle: () => <Text>Text</Text>, headerRight: () => ( <Button onPress={() => alert('This is a button!')} title="Info" color="black" /> ), }} /> </Stack.Navigator> ); } function App() { return ( <NavigationContainer> <StackScreen /> </NavigationContainer> ); } export default App; Tab.Navigator import * as React from 'react'; import { Text, View, Button } from 'react-native'; import { NavigationContainer } from '@react-navigation/native'; import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'; import Ionicons from 'react-native-vector-icons/Ionicons'; function HomeScreen({ navigation }) { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text>Home!</Text> <Button title="Go to Settings" onPress={() => navigation.navigate('Settings')} /> </View> ); } function SettingsScreen({ navigation }) { return ( <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}> <Text>Settings!</Text> <Button title="Go to Home" onPress={() => navigation.navigate('Home')} /> </View> ); } export default function App() { const Tab = createBottomTabNavigator(); return ( <NavigationContainer> <Tab.Navigator screenOptions={({ route }) => ({ tabBarIcon: ({ focused, color, size }) => { let iconName; if (route.name === 'Home') { iconName = focused ? 'ios-information-circle' : 'ios-information-circle-outline'; } else if (route.name === 'Settings') { iconName = focused ? 'ios-list' : 'ios-list'; } // You can return any component that you like here! return <Ionicons name={iconName} size={size} color={color} />; }, tabBarActiveTintColor: 'tomato', tabBarInactiveTintColor: 'gray', })} > <Tab.Screen name="Home" component={HomeScreen} options={{ tabBarBadge: 3 }}/> <Tab.Screen name="Settings" component={SettingsScreen} /> </Tab.Navigator> </NavigationContainer> ); } 隐藏顶部导航栏的一些办法

可以设置headerShown: false

<NavigationContainer> <Stack.Navigator initialRouteName="Index"> <Stack.Screen name="Index" component={IndexScreen} options={{ title: "主页" }, {headerShown: false}} /> </Stack.Navigator> </NavigationContainer> <Tab.Navigator> <Tab.Screen name="Home" component={HomeScreen} options={{headerShown:false}} /> <Tab.Screen name="Settings" component={SettingsScreen} /> </Tab.Navigator> Stack Navigation常用配置 <Stack.Screen // 具体参数设定请参考:https://reactnavigation.org/docs/native-stack-navigator#options name="Details" component={DetailsScreen} options={ {title: "详情"}, {animation: "slide_from_right"},// 划入方式 // {headerTitleAlign:"center"}, // 标题居中(近Android,IOS默认居中) // {presentation: "formSheet"}, // 几乎仅IOS支持 {headerShown: true } // 不要隐藏标题,放到最后面写 } /> 综合案例 import * as React from "react"; import { Text, View, Button, Dimensions } from "react-native"; import { NavigationContainer } from "@react-navigation/native"; import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; import Ionicons from "react-native-vector-icons/Ionicons"; import { createNativeStackNavigator } from "@react-navigation/native-stack"; import { SafeAreaView } from "react-native-safe-area-context"; // 主页 function IndexScreen({ navigation }) { function HomeScreen() { return ( <SafeAreaView edges={['top', 'left', 'right']} style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }} > <Button title="Go to Details" onPress={() => navigation.navigate("Details")} /> </SafeAreaView> ); } function SettingsScreen() { return ( <View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}> <Text>Settings!</Text> </View> ); } const Tab = createBottomTabNavigator(); Tab.navigationOptions = ({navigation}) => { // 关键这一行设置 header:null return{ header: null, } }; return ( <Tab.Navigator> <Tab.Screen name="Home" component={HomeScreen} options={{headerShown:false}} /> <Tab.Screen name="Settings" component={SettingsScreen} /> </Tab.Navigator> ); } function DetailsScreen({ navigation }) { return ( <View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}> <Text>Home Screen</Text> <Button title="Go back" onPress={() => navigation.goBack()} /> </View> ); } export default function App() { const Stack = createNativeStackNavigator(); return ( <NavigationContainer> <Stack.Navigator initialRouteName="Index"> <Stack.Screen name="Index" component={IndexScreen} options={ // headerTitleAlign和 headerShown最好别混用 {title: "主页"}, {animation: "slide_from_right"}, {headerShown: false} } /> <Stack.Screen // 具体参数设定请参考:https://reactnavigation.org/docs/native-stack-navigator#options name="Details" component={DetailsScreen} options={ {title: "详情"}, // {headerTitleAlign:"center"}, // 标题居中(近Android,IOS默认居中) // {presentation: "formSheet"}, // 几乎仅IOS支持 {animation: "slide_from_right"},// 划入方式 {headerShown: true } // 不要隐藏标题 } /> </Stack.Navigator> </NavigationContainer> ); }


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #React #navigation #ampgt #0630expo