安装辅助包

  1. npm install @react-navigation/native
  1. npm install react-native-screens react-native-safe-area-context
  1. npm install @react-navigation/native-stack
  1. cd ./FirstApp/ios && pod install
  1. cd FirstApp
  2. npx react-native start
  1. cd FirstApp
  2. npx react-native run-ios
  1. // In App.js in a new project
  2. import * as React from 'react';
  3. import { View, Text } from 'react-native';
  4. import { NavigationContainer } from '@react-navigation/native';
  5. import { createNativeStackNavigator } from '@react-navigation/native-stack';
  6. function HomeScreen() {
  7. return (
  8. <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
  9. <Text>Home Screen</Text>
  10. </View>
  11. );
  12. }
  13. const Stack = createNativeStackNavigator();
  14. function App() {
  15. return (
  16. <NavigationContainer>
  17. <Stack.Navigator>
  18. <Stack.Screen name="Home" component={HomeScreen} />
  19. </Stack.Navigator>
  20. </NavigationContainer>
  21. );
  22. }
  23. export default App;

基本概念方法的总结

Hello React Navigation

  • React Native doesn’t have a built-in API for navigation like a web browser does. React Navigation provides this for you, along with the iOS and Android gestures and animations to transition between screens.
  • Stack.Navigator is a component that takes route configuration as its children with additional props for configuration and renders our content.
  • Each Stack.Screen component takes a name prop which refers to the name of the route and component prop which specifies the component to render for the route. These are the 2 required props.
  • To specify what the initial route in a stack is, provide an initialRouteName as the prop for the navigator.
  • To specify screen-specific options, we can pass an options prop to Stack.Screen, and for common options, we can pass screenOptions to Stack.Navigator

  • React Native不像网页浏览器那样内置导航API。React Navigation为您提供了这一点,以及iOS和Android手势和动画,以便在屏幕之间过渡。

  • Stack.Navigator是一个以路由配置为子组件,具有额外的配置道具并呈现我们的内容。
  • 每个Stack.Screen组件都使用一个name道具,该名称道具指的是路由的名称和component道具,该道具指定要为路由渲染的组件。这些是2个必需的道具。
  • 要指定堆栈中的初始路由是什么,请提供initialRouteName作为导航器的道具。
  • 要指定特定于屏幕的选项,我们可以将options道具传递给Stack.Screen,对于常见选项,我们可以将screenOptions传递给Stack.Navigator

    Moving between screens

  • navigation.navigate(‘RouteName’) pushes a new route to the native stack navigator if it’s not already in the stack, otherwise it jumps to that screen.

  • We can call navigation.push(‘RouteName’) as many times as we like and it will continue pushing routes.
  • The header bar will automatically show a back button, but you can programmatically go back by calling navigation.goBack(). On Android, the hardware back button just works as expected.
  • You can go back to an existing screen in the stack with navigation.navigate(‘RouteName’), and you can go back to the first screen in the stack with navigation.popToTop().
  • The navigation prop is available to all screen components (components defined as screens in route configuration and rendered by React Navigation as a route).

  • navigation.navigate(‘RouteName’)如果新路由尚未在堆栈中,则将其推送到本机堆栈导航器,否则它会跳转到该屏幕。

  • 我们可以根据需要多次调用 navigation.push(‘RouteName’),它将继续推送路线。
  • 标题栏将自动显示一个后退按钮,但您可以通过调用navigation.goBack()以编程方式返回。在Android上,硬件后退按钮工作正常。
  • You can go back to an existing screen in the stack with navigation.navigate(‘RouteName’), and you can go back to the first screen in the stack with navigation.popToTop().
  • navigation道具适用于所有屏幕组件(在路由配置中定义为屏幕并由React Navigation渲染为路由的组件)。

Passing parameters to routes

  • navigate and push accept an optional second argument to let you pass parameters to the route you are navigating to. For example: navigation.navigate('RouteName', { paramName: 'value' }).
  • You can read the params through route.params inside a screen
  • You can update the screen’s params with navigation.setParams
  • Initial params can be passed via the initialParams prop on Screen
  • Params should contain the minimal data required to show a screen, nothing more

  • navigate并push接受可选的第二个参数,以便您将参数传递到导航到的路线。例如: navigation.navigate(‘RouteName’, { paramName: ‘value’ })

  • You can read the params through route.params inside a screen
  • 您可以使用navigation.setParams
  • 初始参数可以通过initialParams道具传递Screen
  • 参数应该包含显示屏幕所需的最小数据,仅此而已

如果您有嵌套导航器,您需要以不同的方式传递参数。例如,假设您在Account屏幕内有一个导航器,并希望将参数传递到该导航器内的Settings屏幕。然后,您可以通过以下参数传递:

  1. navigation.navigate('Account', {
  2. screen: 'Settings',
  3. params: { user: 'jane' },
  4. });

Configuring the header bar

  • You can customize the header inside of the options prop of your screen components. Read the full list of options in the API reference.
  • The options prop can be an object or a function. When it is a function, it is provided with an object with the navigation and route prop.
  • You can also specify shared screenOptions in the stack navigator configuration when you initialize it. The prop takes precedence over that configuration.

  • 您可以自定义屏幕组件options道具内的标题。阅读API参考中的完整选项列表。

  • options道具可以是对象或函数。当它是一个函数时,它会被提供一个带有当时navigation和route道具的对象。
  • 您还可以在初始化堆栈导航器配置时指定共享screenOptions。道具优先于该配置。

可以在createNativeStackNavigator引用中阅读本机堆栈导航器内部屏幕可用options的完整列表。

Header buttons

  • You can set buttons in the header through the headerLeft and headerRight properties in options.
  • The back button is fully customizable with headerLeft, but if you just want to change the title or image, there are other options for that — headerBackTitle, headerBackTitleStyle, and headerBackImageSource.
  • You can use a callback for the options prop to access navigation and route objects.

  • 您可以通过options中的headerLeft和headerRight属性在标题中设置按钮。

  • 返回按钮可以使用headerLeft完全自定义,但如果您只想更改标题或图像,还有其他options——headerBackTitle、headerBackTitleStyle和headerBackImageSource。
  • 您可以使用选项道具的回调来访问navigation和route对象。

综合修改后的源码

  1. // In App.js in a new project
  2. import * as React from 'react';
  3. import { View, Text, Button, TextInput, Image, Alert } from 'react-native';
  4. import { NavigationContainer } from '@react-navigation/native';
  5. import { createNativeStackNavigator } from '@react-navigation/native-stack';
  6. const HomeScreen = ({ navigation, route }: any) => {
  7. const [count, setCount] = React.useState(0);
  8. React.useLayoutEffect(() => {
  9. navigation.setOptions({
  10. headerRight: () => (
  11. <Button onPress={() => setCount(c => c + 1)} title="Update count" />
  12. ),
  13. });
  14. }, [navigation]);
  15. return (
  16. <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
  17. <Text>Home Screen</Text>
  18. <Text>Count: {count}</Text>
  19. <Button
  20. title="Go to Details"
  21. onPress={() => navigation.navigate('Details')}
  22. /*,{
  23. itemId: 86,
  24. otherParam: 'anything you want here',
  25. })}*/
  26. />
  27. <Button
  28. title="Create post"
  29. onPress={() => navigation.navigate('CreatePost')}
  30. />
  31. <Text style={{ margin: 10 }}>Post: {route.params?.post}</Text>
  32. </View>
  33. );
  34. }
  35. const DetailsScreen = ({navigation, route}: any) => {
  36. const { itemId, otherParam } = route.params;
  37. navigation.setOptions({
  38. title: "Detail " + itemId
  39. })
  40. return (
  41. <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
  42. <Text>Details Screen</Text>
  43. <Text>itemId: {JSON.stringify(itemId)}</Text>
  44. <Text>otherParam: {JSON.stringify(otherParam)}</Text>
  45. <Button
  46. title="Call setParams to change itemId"
  47. onPress={() => navigation.setParams({
  48. itemId: Math.floor(Math.random() * 100)
  49. })}
  50. />
  51. <Button
  52. title="Navigate to Details... again"
  53. onPress={() => navigation.navigate('Details')}
  54. />
  55. <Button
  56. title="Push to Details... again"
  57. onPress={() => navigation.push('Details', {
  58. itemId: Math.floor(Math.random() * 100),
  59. })}
  60. />
  61. <Button title="Go to Home" onPress={() => navigation.navigate('Home')} />
  62. <Button title="Go back" onPress={() => navigation.goBack()} />
  63. <Button
  64. title="Go back to first screen in stack"
  65. onPress={() => navigation.popToTop()}
  66. />
  67. </View>
  68. );
  69. }
  70. const CreatePostScreen = ({ navigation}: any ) => {
  71. const [postText, setPostText] = React.useState('');
  72. return (
  73. <>
  74. <TextInput
  75. multiline
  76. placeholder="What's on your mind?"
  77. style={{ height: 200, padding: 10, backgroundColor: 'white' }}
  78. value={postText}
  79. onChangeText={setPostText}
  80. />
  81. <Button
  82. title="Done"
  83. onPress={() => {
  84. navigation.navigate({
  85. name: 'Home',
  86. params: { post: postText },
  87. merge: true,
  88. });
  89. }}
  90. />
  91. </>
  92. )
  93. }
  94. const defaultStyle = {
  95. headerStyle: {
  96. backgroundColor: '#f4511e',
  97. },
  98. headerTintColor: '#fff',
  99. headerTitleStyle: {
  100. fontWeight: 'bold',
  101. },
  102. }
  103. const screenOptions = {
  104. title: 'Overview',
  105. headerTintColor: '#000',
  106. headerTitle: (props: any) => <LogoTitle {...props} /> ,
  107. /*
  108. headerRight: () => (
  109. <Button
  110. onPress={() => Alert.alert('This is a button!')}
  111. title="Info"
  112. color="#fff"
  113. />
  114. ),*/
  115. }
  116. const LogoTitle = () => {
  117. return (
  118. <Image
  119. style={{ width: 25, height: 25 }}
  120. source={require('react-native/Libraries/NewAppScreen/components/logo.png')}
  121. />
  122. );
  123. }
  124. const detailScreenInitialParams = {
  125. itemId: 88
  126. }
  127. const PageStack = createNativeStackNavigator();
  128. const App = () => {
  129. return (
  130. <NavigationContainer>
  131. <PageStack.Navigator initialRouteName="Home" screenOptions={defaultStyle}>
  132. <PageStack.Screen name="Home" component={HomeScreen} options={screenOptions} />
  133. <PageStack.Screen name="Details" component={DetailsScreen} initialParams={detailScreenInitialParams}/>
  134. <PageStack.Screen name="CreatePost" component={CreatePostScreen} options={{title: "Create Post"}}/>
  135. </PageStack.Navigator>
  136. </NavigationContainer>
  137. );
  138. }
  139. export default App;

嵌套导航器

https://reactnavigation.org/docs/nesting-navigators

导航生命周期

https://reactnavigation.org/docs/navigation-lifecycle

小结

现在你应该熟悉了如何创建本机堆栈导航器,在屏幕组件上配置它,在路由之间导航,以及显示全屏模式。本机堆栈导航器及其相关API将是React导航工具带中最常用的工具,但有些问题无法解决。例如,您无法使用堆栈导航器构建基于选项卡的导航——为此,你需要使用TabNavigator。