react-native-navigation的迁移库

basic-navigation.mdx 9.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. ---
  2. id: basic-navigation
  3. title: Basic navigation
  4. sidebar_label: Basic navigation
  5. ---
  6. import useBaseUrl from '@docusaurus/useBaseUrl';
  7. Generally, any mobile app consists of various destinations which display some content to the user. And in vast majority of cases using an app means navigating between these destinations. React-native-navigation provides ways for you to layout your content on user screen in a logical and performant manner.
  8. React Native Navigation's stack layout lets you push screens, and also navigate back to previous screens. Screens pushed into the stack hide the previous screen in the stack, making the user focus on a single screen at a time. Let's look at a stack layout that provides basic navigation for an app.
  9. ## Creating a stack
  10. ```jsx
  11. // In index.js of a new project
  12. const { Navigation } = require('react-native-navigation');
  13. const React = require('react');
  14. const { View, Text, StyleSheet } = require('react-native');
  15. const HomeScreen = (props) => {
  16. return (
  17. <View style={styles.home}>
  18. <Text>Home Screen</Text>
  19. </View>
  20. );
  21. };
  22. Navigation.registerComponent('Home', () => HomeScreen);
  23. Navigation.events().registerAppLaunchedListener(async () => {
  24. Navigation.setRoot({
  25. root: {
  26. stack: {
  27. children: [
  28. {
  29. component: {
  30. name: 'Home'
  31. }
  32. }
  33. ]
  34. }
  35. }
  36. });
  37. });
  38. const styles = StyleSheet.create({
  39. root: {
  40. flex: 1,
  41. alignItems: 'center',
  42. justifyContent: 'center',
  43. backgroundColor: 'whitesmoke'
  44. }
  45. });
  46. ```
  47. Running this code will render a screen with an empty TopBar and your HomeScreen component (shown below). The TopBar is part of the stack layout, we'll work on configuring it later.
  48. <img width="40%" src={useBaseUrl('img/stack1.png')} />
  49. ## Specifying options
  50. You can specify options of each layout (Stack, component pushed into a stack, etc.) to configure various parameters like the TopBar title or color. Lets spice things up by changing the TopBar color and while we're at it, also move the title to the TopBar.
  51. Lets change the Home screen declaration to the following and reload the app to see the changes.
  52. ```jsx
  53. const HomeScreen = (props) => {
  54. return (
  55. <View style={styles.home}>
  56. <Text>Hello React Native Navigation 👋</Text>
  57. </View>
  58. );
  59. };
  60. HomeScreen.options = {
  61. topBar: {
  62. title: {
  63. text: 'Home',
  64. color: 'white'
  65. },
  66. background: {
  67. color: '#4d089a'
  68. }
  69. }
  70. }
  71. ```
  72. Our app should now look like this:
  73. <img width="40%" src={useBaseUrl('img/stackOptions.png')} />
  74. ## Navigating in a stack
  75. In the previous section we created a stack and initialized it with a single child. We'll now learn how to add another child to the stack. From now on, we'll call the action of adding children to the stack 'push', and removing children - 'pop'.
  76. In order to push another screen to the stack, we will add a button to the home screen and call `Navigation.push`. The 'push' command accepts two parameters, the first is the id used to indicate into which stack to push the screen and the second is the screen we're pushing. After pushing a screen, a back button is added automatically to the TopBar so the users can navigate easily back to the previous screen.
  77. You can read more about the stack layout [here](stack-doc.mdx) or dive right into the API [here](stack-api.mdx).
  78. :::info componentId
  79. Each React component registered with `Navigation.registerComponent` is assigned a unique `componentId` by Navigation. This unique id is used with Navigation commands (like the push command) to indicate into which stack we'd like to push. In this case, by using the componentId of the Home screen, we are telling Navigation to push into the stack containing the Home screen.
  80. :::
  81. ```js
  82. Navigation.push(props.componentId, {
  83. component: {
  84. name: 'Settings', // Push the screen registered with the 'Settings' key
  85. options: { // Optional options object to configure the screen
  86. topBar: {
  87. title: {
  88. text: 'Settings' // Set the TopBar title of the new Screen
  89. }
  90. }
  91. }
  92. }
  93. });
  94. ```
  95. Lets change our code to the following snippet below and reload the app. Now our Home should contain a button which when pressed, pushes a new screen into the stack. We've successfully navigated to a new screen! 👏
  96. ```jsx
  97. // In index.js of a new project
  98. const { Navigation } = require('react-native-navigation');
  99. const React = require('react');
  100. const { View, Text, Button, StyleSheet } = require('react-native');
  101. // Settings screen declaration - this is the screen we'll be pushing into the stack
  102. const SettingsScreen = () => {
  103. return (
  104. <View style={[styles.root, styles.settings]}>
  105. <Text>Settings Screen</Text>
  106. </View>
  107. );
  108. };
  109. // Home screen declaration
  110. const HomeScreen = (props) => {
  111. return (
  112. <View style={styles.root}>
  113. <Text>Hello React Native Navigation 👋</Text>
  114. <Button
  115. title='Push Settings Screen'
  116. color='#710ce3'
  117. onPress={() => Navigation.push(props.componentId, {
  118. component: {
  119. name: 'Settings',
  120. options: {
  121. topBar: {
  122. title: {
  123. text: 'Settings'
  124. }
  125. }
  126. }
  127. }
  128. })}/>
  129. </View>
  130. );
  131. };
  132. HomeScreen.options = {
  133. topBar: {
  134. title: {
  135. text: 'Home',
  136. color: 'white'
  137. },
  138. background: {
  139. color: '#4d089a'
  140. }
  141. }
  142. };
  143. const SettingsScreen = () => {
  144. return (
  145. <View style={styles.root}>
  146. <Text>Settings Screen</Text>
  147. </View>
  148. );
  149. }
  150. Navigation.registerComponent('Home', () => HomeScreen);
  151. Navigation.registerComponent('Settings', () => SettingsScreen);
  152. Navigation.events().registerAppLaunchedListener(async () => {
  153. Navigation.setRoot({
  154. root: {
  155. stack: {
  156. children: [
  157. {
  158. component: {
  159. name: 'Home'
  160. }
  161. }
  162. ]
  163. }
  164. }
  165. });
  166. });
  167. const styles = StyleSheet.create({
  168. root: {
  169. flex: 1,
  170. alignItems: 'center',
  171. justifyContent: 'center',
  172. backgroundColor: 'whitesmoke'
  173. }
  174. });
  175. ```
  176. <img width="40%" src={useBaseUrl('img/stack2.gif')} />
  177. ## App theme
  178. Our app is growing and already contains two screens. This introduces a new problem - while the home screen has a nice purple TopBar, our settings screen seems pretty dull as it still uses the default system look and feel.
  179. Currently, our style declaration applies only to the Home screen, so lets apply it to all of our screens by using `Navigation.setDefaultOptions`.
  180. ```js
  181. Navigation.setDefaultOptions({
  182. statusBar: {
  183. backgroundColor: '#4d089a'
  184. },
  185. topBar: {
  186. title: {
  187. color: 'white'
  188. },
  189. backButton: {
  190. color: 'white'
  191. },
  192. background: {
  193. color: '#4d089a'
  194. }
  195. }
  196. });
  197. ```
  198. We need to add this snippet before registering the `registerAppLaunchedListener`. This way we ensure our theme is applied when our root is set. Our code should now look like this:
  199. ```jsx
  200. // In index.js of a new project
  201. const { Navigation } = require('react-native-navigation');
  202. const React = require('react');
  203. const { View, Text, Button, StyleSheet } = require('react-native');
  204. // Settings screen declaration - this is the screen we'll be pushing into the stack
  205. const SettingsScreen = () => {
  206. return (
  207. <View style={[styles.root, styles.settings]}>
  208. <Text>Settings Screen</Text>
  209. </View>
  210. );
  211. };
  212. // Home screen declaration
  213. const HomeScreen = (props) => {
  214. return (
  215. <View style={styles.root}>
  216. <Text>Hello React Native Navigation 👋</Text>
  217. <Button
  218. title='Push Settings Screen'
  219. color='#710ce3'
  220. onPress={() => Navigation.push(props.componentId, {
  221. component: {
  222. name: 'Settings',
  223. options: {
  224. topBar: {
  225. title: {
  226. text: 'Settings'
  227. }
  228. }
  229. }
  230. }
  231. })}/>
  232. </View>
  233. );
  234. };
  235. HomeScreen.options = {
  236. topBar: {
  237. title: {
  238. text: 'Home',
  239. }
  240. }
  241. };
  242. const SettingsScreen = () => {
  243. return (
  244. <View style={styles.root}>
  245. <Text>Settings Screen</Text>
  246. </View>
  247. );
  248. }
  249. Navigation.registerComponent('Home', () => HomeScreen);
  250. Navigation.registerComponent('Settings', () => SettingsScreen);
  251. Navigation.setDefaultOptions({
  252. statusBar: {
  253. backgroundColor: '#4d089a'
  254. },
  255. topBar: {
  256. title: {
  257. color: 'white'
  258. },
  259. backButton: {
  260. color: 'white'
  261. },
  262. background: {
  263. color: '#4d089a'
  264. }
  265. }
  266. });
  267. Navigation.events().registerAppLaunchedListener(async () => {
  268. Navigation.setRoot({
  269. root: {
  270. stack: {
  271. children: [
  272. {
  273. component: {
  274. name: 'Home'
  275. }
  276. }
  277. ]
  278. }
  279. }
  280. });
  281. });
  282. const styles = StyleSheet.create({
  283. root: {
  284. flex: 1,
  285. alignItems: 'center',
  286. justifyContent: 'center',
  287. backgroundColor: 'whitesmoke'
  288. }
  289. });
  290. ```
  291. Lets run our code again - now our design is consistent across both screens.
  292. <img width="40%" src={useBaseUrl('img/stack3.gif')} />
  293. ## Summary
  294. We've learned the basics of navigation with React Native Navigation by implementing a stack and pushing screens into it.
  295. We've also learned a few methods of applying styles to our screens and layouts with the Options mechanism.
  296. * Navigation.setRoot() sets the root layout of our app. The initial root has to be set from an `AppLaunchedEvent` callback.
  297. * Options can be applied directly to components.
  298. * Screens can be added to a stack with the `Navigation.push()` command.
  299. * Components registered with `Navigation.registerComponent()` are injected with a `componentId` which is used when navigating.
  300. * Themes are applied via the `Navigation.setDefaultOptions()` command.
  301. In the next section we'll explore a more advance navigation patters using BottomTabs layout and also see how, and why, multiple roots are set.