1 00:00:00,000 --> 00:00:02,490 [MUSIC PLAYING] 2 00:00:02,490 --> 00:00:15,960 3 00:00:15,960 --> 00:00:18,480 SPEAKER: Hello and welcome back for lecture 6. 4 00:00:18,480 --> 00:00:21,240 So in the previous lecture we covered a few things-- 5 00:00:21,240 --> 00:00:23,850 user input and how to use text input. 6 00:00:23,850 --> 00:00:26,640 We covered some simple input validation to just make sure 7 00:00:26,640 --> 00:00:29,296 that the input that we receive is the input that we want. 8 00:00:29,296 --> 00:00:31,170 We talked about keyboard avoiding view, which 9 00:00:31,170 --> 00:00:35,010 is built into React Native, which allows us to move inputs out 10 00:00:35,010 --> 00:00:38,280 of the way as the keyboard, the virtual keyboard appears. 11 00:00:38,280 --> 00:00:41,250 We talked about some various debugging strategies, 12 00:00:41,250 --> 00:00:43,042 how to log errors and warnings. 13 00:00:43,042 --> 00:00:45,000 We talked about Chrome Developer Tools, and how 14 00:00:45,000 --> 00:00:49,140 to send our JavaScript to be executed there rather than on the device itself. 15 00:00:49,140 --> 00:00:51,870 We talked about the React Native Inspector and react-devtools 16 00:00:51,870 --> 00:00:55,350 to other ways of viewing the UI, and to solve 17 00:00:55,350 --> 00:00:57,510 bugs that have to do with UI things. 18 00:00:57,510 --> 00:01:00,480 And finally, we talked about installing external libraries with npm. 19 00:01:00,480 --> 00:01:02,910 And there I alluded to the library that we're going 20 00:01:02,910 --> 00:01:04,920 to start using called React Navigation. 21 00:01:04,920 --> 00:01:08,850 And today we're joined by Eric and Brent here, 22 00:01:08,850 --> 00:01:12,960 who were co-authors of this library called React Navigation. 23 00:01:12,960 --> 00:01:17,640 Brent, right here, works at Expo, and he helped write React Navigation. 24 00:01:17,640 --> 00:01:21,720 And Eric, over here, was on the React Native team at Facebook, 25 00:01:21,720 --> 00:01:24,300 and also helped write the React Navigation library. 26 00:01:24,300 --> 00:01:27,719 So I'll turn it over to them for React Navigation. 27 00:01:27,719 --> 00:01:28,260 BRENT: Great. 28 00:01:28,260 --> 00:01:28,759 Thank you. 29 00:01:28,759 --> 00:01:31,890 30 00:01:31,890 --> 00:01:32,850 All right. 31 00:01:32,850 --> 00:01:35,370 So I think the first question we need to answer here 32 00:01:35,370 --> 00:01:38,460 is, what is navigation exactly? 33 00:01:38,460 --> 00:01:40,840 So navigation is a pretty broad term. 34 00:01:40,840 --> 00:01:46,440 It covers pretty much any topic related to moving between screens in your app, 35 00:01:46,440 --> 00:01:50,260 or moving between different locations in your app. 36 00:01:50,260 --> 00:01:53,160 Web navigation you might be familiar with already, 37 00:01:53,160 --> 00:01:55,830 which is very oriented around URLs. 38 00:01:55,830 --> 00:01:58,980 You enter something into the URL bar, and as a result 39 00:01:58,980 --> 00:02:03,270 of that changing you change the screen that you're on, or potentially just 40 00:02:03,270 --> 00:02:05,760 an entirely different website. 41 00:02:05,760 --> 00:02:09,539 Mobile apps don't really use URLs so much, at least not 42 00:02:09,539 --> 00:02:12,120 for navigating within the app. 43 00:02:12,120 --> 00:02:16,440 Usually in mobile apps, URLs are used for something called deep linking. 44 00:02:16,440 --> 00:02:18,390 We won't be talking about that too much today, 45 00:02:18,390 --> 00:02:20,325 so I've just added a link here to the slide. 46 00:02:20,325 --> 00:02:24,120 So if you want to learn more about deep linking, you can follow that. 47 00:02:24,120 --> 00:02:27,800 So the navigation APIs are very different between iOS and Android. 48 00:02:27,800 --> 00:02:31,770 They could not be really more different at all. 49 00:02:31,770 --> 00:02:35,160 There's almost no similarities, honestly. 50 00:02:35,160 --> 00:02:38,580 And so it's quite a challenge to do what React Native is 51 00:02:38,580 --> 00:02:43,320 trying to do in many regards in the realm of navigation. 52 00:02:43,320 --> 00:02:47,040 And try and bring these together and make a kind of platform-agnostic API 53 00:02:47,040 --> 00:02:52,470 for how to use these different platform-specific patterns 54 00:02:52,470 --> 00:02:57,210 for navigation, while also making the API for interfacing with that 55 00:02:57,210 --> 00:02:59,590 very similar across platforms. 56 00:02:59,590 --> 00:03:03,479 And so there are several libraries that attempt to solve this problem. 57 00:03:03,479 --> 00:03:05,520 We're going to talk about React Navigation today. 58 00:03:05,520 --> 00:03:08,460 59 00:03:08,460 --> 00:03:12,290 So again, just to give you a gut feeling of what we're talking about, 60 00:03:12,290 --> 00:03:15,410 on the web with the desktop web browser, this 61 00:03:15,410 --> 00:03:18,950 is typically what you would consider navigation. 62 00:03:18,950 --> 00:03:21,890 You scroll somewhere, you click a link, it brings you 63 00:03:21,890 --> 00:03:24,740 to another URL, the page changes. 64 00:03:24,740 --> 00:03:28,760 There is a Back button, a Refresh button, Forward button, 65 00:03:28,760 --> 00:03:32,000 and an address bar. 66 00:03:32,000 --> 00:03:38,070 On mobile, with a mobile browser it's very similar. 67 00:03:38,070 --> 00:03:40,730 The main distinction that you'll see on mobile 68 00:03:40,730 --> 00:03:45,710 is that there is some UI that you get for free, actually, 69 00:03:45,710 --> 00:03:49,190 with a mobile web browser, where you can swipe back on your screen 70 00:03:49,190 --> 00:03:51,680 or swipe forward on your screen, and that 71 00:03:51,680 --> 00:03:54,740 will allow you to navigate between different pages 72 00:03:54,740 --> 00:03:59,060 that you visited in your history. 73 00:03:59,060 --> 00:04:01,370 The tradeoff here with having these gestures 74 00:04:01,370 --> 00:04:03,810 is that you actually have very little control over them. 75 00:04:03,810 --> 00:04:05,976 So they're there whether you want to use the gesture 76 00:04:05,976 --> 00:04:07,840 for something else on your page or not. 77 00:04:07,840 --> 00:04:09,740 You're just kind of stuck with them. 78 00:04:09,740 --> 00:04:11,930 And the same thing is true for the navigation 79 00:04:11,930 --> 00:04:16,850 bar on the bottom of the screen with the Back button and various other options. 80 00:04:16,850 --> 00:04:19,952 That does interfere with putting content near the bottom of the screen. 81 00:04:19,952 --> 00:04:22,160 So when it is hidden and you attempt to tap something 82 00:04:22,160 --> 00:04:24,080 on the bottom of the screen, it shows up. 83 00:04:24,080 --> 00:04:26,780 And you have to tap again. 84 00:04:26,780 --> 00:04:29,960 So you get a lot, but there are some costs to it. 85 00:04:29,960 --> 00:04:33,560 Mobile navigation feels more like this, where maybe you have a Tab 86 00:04:33,560 --> 00:04:36,050 bar on the bottom like this one. 87 00:04:36,050 --> 00:04:38,870 You move between various screens. 88 00:04:38,870 --> 00:04:43,490 When you tap on some link to go to another screen within the app, 89 00:04:43,490 --> 00:04:46,880 it might slide in over top, and you can swipe back from there. 90 00:04:46,880 --> 00:04:49,460 And really the key thing here is that you kind of control 91 00:04:49,460 --> 00:04:52,400 the entire experience as an app developer. 92 00:04:52,400 --> 00:04:56,300 It's almost like you have your own sort of browser implementation, 93 00:04:56,300 --> 00:05:00,200 but the only content that you're browsing is the content of your app. 94 00:05:00,200 --> 00:05:04,580 And the actual behavior that you get out of navigation in your app 95 00:05:04,580 --> 00:05:09,060 is entirely up to you. 96 00:05:09,060 --> 00:05:17,300 So React Navigation is distinguished from some other libraries in the React 97 00:05:17,300 --> 00:05:23,030 Native ecosystem in terms of how it approaches implementing navigation. 98 00:05:23,030 --> 00:05:27,690 So there's two distinct approaches. 99 00:05:27,690 --> 00:05:34,280 The first one is to mainly implement the logic and the views in JavaScript. 100 00:05:34,280 --> 00:05:37,250 And so the majority of your implementation 101 00:05:37,250 --> 00:05:41,150 is just plain React all the way down in the stack. 102 00:05:41,150 --> 00:05:44,660 A second alternative approach is to write 103 00:05:44,660 --> 00:05:51,560 a wrapper for the existing native APIs that exist on iOS and Android, 104 00:05:51,560 --> 00:05:55,010 and try to smooth those differences out using 105 00:05:55,010 --> 00:05:58,280 just basically an alternative front-end API for how 106 00:05:58,280 --> 00:06:02,100 you interact with these APIs. 107 00:06:02,100 --> 00:06:05,900 React Navigation takes the first approach. 108 00:06:05,900 --> 00:06:08,060 I won't go into too many details here. 109 00:06:08,060 --> 00:06:10,730 There are some things that are self-evident from just looking 110 00:06:10,730 --> 00:06:17,180 at the characterizing feature of the approach in that, if it's mainly 111 00:06:17,180 --> 00:06:19,580 in JavaScript and you are a JavaScript developer, 112 00:06:19,580 --> 00:06:23,060 you will know how to work with any part of the tool. 113 00:06:23,060 --> 00:06:27,110 Whereas if you wrap a native API, you suddenly, 114 00:06:27,110 --> 00:06:30,950 when you want to extend it or change something or debug a problem, 115 00:06:30,950 --> 00:06:35,150 you have to become familiar with Swift or Objective-C or Java Kotlin 116 00:06:35,150 --> 00:06:36,380 or something like that. 117 00:06:36,380 --> 00:06:39,130 So we chose the first approach here. 118 00:06:39,130 --> 00:06:41,420 And there's more information in the docs which 119 00:06:41,420 --> 00:06:44,780 I've linked to here, as well as some information on alternative libraries 120 00:06:44,780 --> 00:06:48,720 if this isn't your preferred approach. 121 00:06:48,720 --> 00:06:53,010 So first thing we're going to do here is install React Navigation. 122 00:06:53,010 --> 00:06:58,340 So as you saw last lecture, npm install, library name, dash dash 123 00:06:58,340 --> 00:07:00,950 save, depending on the version of npm that you're using. 124 00:07:00,950 --> 00:07:03,737 Newer versions that's not necessary. 125 00:07:03,737 --> 00:07:05,570 One thing that's a little bit different here 126 00:07:05,570 --> 00:07:09,920 is that we've specified a version number explicitly. 127 00:07:09,920 --> 00:07:13,070 Typically, if you install with just the React Navigation package, 128 00:07:13,070 --> 00:07:16,980 it will get the latest stable version of the package. 129 00:07:16,980 --> 00:07:20,090 However, for the sake of this lecture, we 130 00:07:20,090 --> 00:07:23,510 are just about to release a new version of React Navigation. 131 00:07:23,510 --> 00:07:27,350 Currently the stable version is 1.5 or so. 132 00:07:27,350 --> 00:07:30,810 And React Navigation 2 has some significant differences. 133 00:07:30,810 --> 00:07:34,610 So we wanted to make sure that the things that you're learning today 134 00:07:34,610 --> 00:07:36,170 don't go out of date next week. 135 00:07:36,170 --> 00:07:39,120 136 00:07:39,120 --> 00:07:41,720 So if you're referring to this in the future, keep in mind 137 00:07:41,720 --> 00:07:46,310 you should use a 2.x series of releases. 138 00:07:46,310 --> 00:07:49,340 So some key concepts before we really get into the code here. 139 00:07:49,340 --> 00:07:55,070 I think it's worth clarifying these three big terms in React Navigation. 140 00:07:55,070 --> 00:07:56,700 You're going to see these a lot. 141 00:07:56,700 --> 00:07:58,700 The first one is navigator, the second one 142 00:07:58,700 --> 00:08:02,180 is routes, and then screen components. 143 00:08:02,180 --> 00:08:07,370 So a navigator is a component that implements a navigation pattern. 144 00:08:07,370 --> 00:08:11,690 So an example would be in the mobile app that we saw in that video 145 00:08:11,690 --> 00:08:16,640 just moments ago, the tabs are a certain navigation pattern, 146 00:08:16,640 --> 00:08:20,180 and you would have a navigator that is associated with that pattern. 147 00:08:20,180 --> 00:08:24,150 We'll see in more detail, of course, what that means shortly. 148 00:08:24,150 --> 00:08:26,450 Another type is a stack navigator. 149 00:08:26,450 --> 00:08:29,990 So when you tap on something and it pushes a new screen onto the stack, 150 00:08:29,990 --> 00:08:32,809 and so on and so on as you add more screens. 151 00:08:32,809 --> 00:08:35,570 And it gives you the swipe-back behavior. 152 00:08:35,570 --> 00:08:40,770 So each navigator has one or more routes. 153 00:08:40,770 --> 00:08:46,391 A navigator is a parent of a route, and a route is a child of a navigator. 154 00:08:46,391 --> 00:08:48,140 Don't worry too much about this right now. 155 00:08:48,140 --> 00:08:51,080 It will become more clear very shortly. 156 00:08:51,080 --> 00:08:55,170 I just want to make sure we're clear up front on exactly what these are. 157 00:08:55,170 --> 00:08:58,460 So each route must have a name and a screen component. 158 00:08:58,460 --> 00:09:02,420 So the name is usually unique across the app. 159 00:09:02,420 --> 00:09:07,820 That's a safe assumption to make, at least for now and the near future. 160 00:09:07,820 --> 00:09:10,839 When you get in some more complicated use cases it may not be true. 161 00:09:10,839 --> 00:09:13,130 But you will hopefully have the intuition at that point 162 00:09:13,130 --> 00:09:17,240 to understand why that is the case. 163 00:09:17,240 --> 00:09:20,135 The screen component is a React component that 164 00:09:20,135 --> 00:09:22,280 is rendered when the route is active. 165 00:09:22,280 --> 00:09:27,050 So in the tab, for example, that we saw, there 166 00:09:27,050 --> 00:09:32,690 is a screen associated with the Feed tab, 167 00:09:32,690 --> 00:09:36,390 and there is a screen associated with the Settings tab, and Search tab, 168 00:09:36,390 --> 00:09:37,040 and so on. 169 00:09:37,040 --> 00:09:41,840 And so those, in React Navigation, are React components. 170 00:09:41,840 --> 00:09:44,330 Now another thing that Eric will speak about a bit 171 00:09:44,330 --> 00:09:48,290 later is that a screen component can also be another navigator. 172 00:09:48,290 --> 00:09:51,290 And this is a powerful concept that would be 173 00:09:51,290 --> 00:09:52,900 very difficult to build apps without. 174 00:09:52,900 --> 00:09:58,210 And so we will discuss that once we have a bit more foundational knowledge. 175 00:09:58,210 --> 00:10:01,730 So we're going to start off with the easiest, most simple navigator, and one 176 00:10:01,730 --> 00:10:05,300 that translates directly from the example that 177 00:10:05,300 --> 00:10:08,800 was being worked on last class, the Contacts List example. 178 00:10:08,800 --> 00:10:11,470 So the Switch Navigator is a navigator that 179 00:10:11,470 --> 00:10:13,960 is capable of displaying one screen at a time. 180 00:10:13,960 --> 00:10:17,140 When a screen goes inactive, it is unmounted, 181 00:10:17,140 --> 00:10:22,240 and the only action the user can take is to say I want to go from this screen 182 00:10:22,240 --> 00:10:24,040 to this other screen. 183 00:10:24,040 --> 00:10:27,110 So it's very straightforward. 184 00:10:27,110 --> 00:10:29,060 It kind of looks like this. 185 00:10:29,060 --> 00:10:32,530 You have screen one, and we have a button, let's say, go to screen two. 186 00:10:32,530 --> 00:10:35,410 If I press Go to Screen Two, it simply does this. 187 00:10:35,410 --> 00:10:36,820 The other one's gone. 188 00:10:36,820 --> 00:10:40,750 The second one appears. 189 00:10:40,750 --> 00:10:42,700 Basically, as you tap on these buttons, you're 190 00:10:42,700 --> 00:10:45,981 just switching between the screens. 191 00:10:45,981 --> 00:10:46,480 All right. 192 00:10:46,480 --> 00:10:50,590 And so to create this navigator, we import createSwitchNavigator 193 00:10:50,590 --> 00:10:52,000 from react-navigation. 194 00:10:52,000 --> 00:10:58,420 We call it with a map where the keys are the names of the routes, 195 00:10:58,420 --> 00:11:03,130 and the values are the screen components. 196 00:11:03,130 --> 00:11:05,620 When we actually want to render it, we just 197 00:11:05,620 --> 00:11:09,370 take the return value of the createSwitchNavigator function, 198 00:11:09,370 --> 00:11:12,640 and we render it inside of our app component. 199 00:11:12,640 --> 00:11:15,670 Usually this is at the root of our app. 200 00:11:15,670 --> 00:11:21,830 And we'll see why that is, again, when we talk about composition. 201 00:11:21,830 --> 00:11:24,250 So this is kind of a new concept here, the idea 202 00:11:24,250 --> 00:11:30,130 of createSwitchNavigator as being a function that returns a component. 203 00:11:30,130 --> 00:11:34,660 So I just wanted to take a moment to explain what that is exactly. 204 00:11:34,660 --> 00:11:39,610 So a createSwitchNavigator is a higher order component, 205 00:11:39,610 --> 00:11:43,040 in that it is a function that returns a React component. 206 00:11:43,040 --> 00:11:48,040 So a higher order component, as defined in the React documentation, 207 00:11:48,040 --> 00:11:52,570 is an advanced technique for reusing component logic. 208 00:11:52,570 --> 00:11:55,210 And so the component logic we're reusing in this case 209 00:11:55,210 --> 00:11:59,080 is the behavior of how a Switch Navigator works. 210 00:11:59,080 --> 00:12:02,200 And we're saying, we want you to be a Switch Navigator that has 211 00:12:02,200 --> 00:12:03,880 these screens and these route names. 212 00:12:03,880 --> 00:12:06,970 And the logic for how it operates given those parameters 213 00:12:06,970 --> 00:12:10,510 is built into the underlying Switch Navigator. 214 00:12:10,510 --> 00:12:13,390 This is pretty similar to the idea of higher order functions, 215 00:12:13,390 --> 00:12:15,550 if you've ever used those before. 216 00:12:15,550 --> 00:12:19,060 So if you've used something like forEach or mapFilter, 217 00:12:19,060 --> 00:12:23,290 those sorts of functions, which are functions that take functions. 218 00:12:23,290 --> 00:12:27,880 Also functions that return functions, those are higher order functions. 219 00:12:27,880 --> 00:12:31,895 And the same thing applies for higher order components. 220 00:12:31,895 --> 00:12:35,010 221 00:12:35,010 --> 00:12:38,870 So when we want to go from one screen to another screen, 222 00:12:38,870 --> 00:12:42,900 we simply call this.props.navigation.navigate, 223 00:12:42,900 --> 00:12:44,840 and we pass in the route name. 224 00:12:44,840 --> 00:12:49,520 So going back here to the definition, you can see the route name corresponds 225 00:12:49,520 --> 00:12:51,300 to the screen component. 226 00:12:51,300 --> 00:12:55,490 And when we call Navigate, we give the route name, 227 00:12:55,490 --> 00:12:59,890 and it simply switches to show the component corresponding to that route 228 00:12:59,890 --> 00:13:00,390 name. 229 00:13:00,390 --> 00:13:03,210 230 00:13:03,210 --> 00:13:07,330 The navigation prop is passed into every screen component automatically. 231 00:13:07,330 --> 00:13:11,490 So it's available on this.props.navigation. 232 00:13:11,490 --> 00:13:15,630 And it has a variety of useful methods available on it. 233 00:13:15,630 --> 00:13:17,640 We're looking at navigate here. 234 00:13:17,640 --> 00:13:22,020 We'll see a little bit more later about goBack and setParams and getParam. 235 00:13:22,020 --> 00:13:25,620 And we won't cover some of these other more advanced ones. 236 00:13:25,620 --> 00:13:28,950 But again, it's worth looking in the documentation for when you want 237 00:13:28,950 --> 00:13:31,631 to learn some more advanced use cases. 238 00:13:31,631 --> 00:13:32,130 All right. 239 00:13:32,130 --> 00:13:33,950 So let's put this to use. 240 00:13:33,950 --> 00:13:37,990 We're going to start our first example. 241 00:13:37,990 --> 00:13:42,390 So the first thing I'm going to do, is I'm going to just open up a new tab 242 00:13:42,390 --> 00:13:47,130 while I run exp start dash dash ios. 243 00:13:47,130 --> 00:13:53,580 So exp is the command line equivalent of xd, which you've been using so far. 244 00:13:53,580 --> 00:13:56,010 I'll make that a little bit bigger for you. 245 00:13:56,010 --> 00:13:57,732 Hopefully that works. 246 00:13:57,732 --> 00:13:59,190 So it's essentially the same thing. 247 00:13:59,190 --> 00:14:04,530 And running exp start ios is just like opening a project in xd 248 00:14:04,530 --> 00:14:08,862 and hitting Open on Device with iOS. 249 00:14:08,862 --> 00:14:12,080 I'm just going to open that here. 250 00:14:12,080 --> 00:14:18,750 While that's going on, I'm going to open up Visual Studio Code. 251 00:14:18,750 --> 00:14:20,270 And we're right inside of our app. 252 00:14:20,270 --> 00:14:21,686 Let's wait for this to start. 253 00:14:21,686 --> 00:14:31,120 254 00:14:31,120 --> 00:14:32,100 OK. 255 00:14:32,100 --> 00:14:33,970 So we have our app up there. 256 00:14:33,970 --> 00:14:38,640 So this is essentially the app that you finished last class. 257 00:14:38,640 --> 00:14:43,050 And we're going to continue on this shortly, but first 258 00:14:43,050 --> 00:14:47,010 let's just build this abstract example of using a Switch Navigator. 259 00:14:47,010 --> 00:14:52,150 And then we'll see how we can integrate that into what we've already built. 260 00:14:52,150 --> 00:14:57,210 So to do that, I'm actually going to go back here and make an examples 261 00:14:57,210 --> 00:14:58,810 directory. 262 00:14:58,810 --> 00:15:03,320 And I'm just going to create a file called examples. 263 00:15:03,320 --> 00:15:04,710 Let's just call it Switch. 264 00:15:04,710 --> 00:15:07,350 0 dash Switch. 265 00:15:07,350 --> 00:15:10,010 And go back in here. 266 00:15:10,010 --> 00:15:12,630 All right. 267 00:15:12,630 --> 00:15:16,740 First thing we're going to do is import React from React. 268 00:15:16,740 --> 00:15:21,130 Let's make that a bit bigger for you, as well. 269 00:15:21,130 --> 00:15:28,405 And as we saw before, createSwitchNavigator 270 00:15:28,405 --> 00:15:32,331 from react-navigation. 271 00:15:32,331 --> 00:15:32,830 OK. 272 00:15:32,830 --> 00:15:38,920 273 00:15:38,920 --> 00:15:40,305 And do class. 274 00:15:40,305 --> 00:15:46,300 275 00:15:46,300 --> 00:15:46,820 OK. 276 00:15:46,820 --> 00:15:48,653 So we know we need to return something here. 277 00:15:48,653 --> 00:15:51,691 278 00:15:51,691 --> 00:15:57,270 We created our app navigator like this, calling SwitchNavigator 279 00:15:57,270 --> 00:16:03,310 and passing in a map of route names and screen components. 280 00:16:03,310 --> 00:16:08,020 So first route name, we'll just go with the example we've been using so far, 281 00:16:08,020 --> 00:16:10,050 and just call it RouteNameOne. 282 00:16:10,050 --> 00:16:14,100 We could call it CS 50, you could call it whatever you want. 283 00:16:14,100 --> 00:16:17,280 But for the sake of demonstration, we'll just call it that. 284 00:16:17,280 --> 00:16:21,060 And now we've run into a situation where we need a screen component. 285 00:16:21,060 --> 00:16:23,730 So let's create one here. 286 00:16:23,730 --> 00:16:27,030 It's just any old React component will do. 287 00:16:27,030 --> 00:16:29,280 I will call it ScreenComponentOne. 288 00:16:29,280 --> 00:16:36,360 289 00:16:36,360 --> 00:16:39,090 Let's import a couple of things from React Native. 290 00:16:39,090 --> 00:16:42,580 Let's do a button and a view. 291 00:16:42,580 --> 00:16:45,400 Just to give some contents to the screen, 292 00:16:45,400 --> 00:16:47,970 so we can actually do something with it. 293 00:16:47,970 --> 00:16:52,120 And render a view. 294 00:16:52,120 --> 00:16:56,220 Let's make it take up the full screen. 295 00:16:56,220 --> 00:17:00,265 Align everything in the middle, justify to the middle. 296 00:17:00,265 --> 00:17:02,970 297 00:17:02,970 --> 00:17:04,720 And let's give it a border, just so we can 298 00:17:04,720 --> 00:17:07,705 see easily the differences between screen one and screen two. 299 00:17:07,705 --> 00:17:12,569 I'm going to say border width is 25, and border color-- 300 00:17:12,569 --> 00:17:14,460 I'll just make it teal here. 301 00:17:14,460 --> 00:17:19,619 302 00:17:19,619 --> 00:17:20,819 Let's add a button. 303 00:17:20,819 --> 00:17:23,300 And we'll do something with that in a moment. 304 00:17:23,300 --> 00:17:28,910 305 00:17:28,910 --> 00:17:30,635 And I'll just format that. 306 00:17:30,635 --> 00:17:33,100 It appears we have an error somewhere. 307 00:17:33,100 --> 00:17:34,680 Ah, perfect. 308 00:17:34,680 --> 00:17:35,640 OK. 309 00:17:35,640 --> 00:17:38,180 So this is some invalid syntax, because we 310 00:17:38,180 --> 00:17:41,670 need to drop in the actual name of the screen component. 311 00:17:41,670 --> 00:17:48,230 So now what we have here is an app navigator which has a single route, 312 00:17:48,230 --> 00:17:54,080 and the route renders the ScreenComponentOne component, which 313 00:17:54,080 --> 00:17:56,840 is simply a button that does absolutely nothing, 314 00:17:56,840 --> 00:18:00,420 but it's centered in the middle of the screen. 315 00:18:00,420 --> 00:18:04,550 Now, to actually have this display in our app, 316 00:18:04,550 --> 00:18:08,450 we need to render the navigator somewhere. 317 00:18:08,450 --> 00:18:14,460 And going back here, we're just going to comment all that out for now. 318 00:18:14,460 --> 00:18:20,810 And import example from examples 0 dash switch. 319 00:18:20,810 --> 00:18:25,350 And render that there. 320 00:18:25,350 --> 00:18:26,665 So if I go back here-- 321 00:18:26,665 --> 00:18:28,460 oh, looks like we have a typo. 322 00:18:28,460 --> 00:18:29,380 Ah, of course. 323 00:18:29,380 --> 00:18:31,250 We missed out on a very important step. 324 00:18:31,250 --> 00:18:34,030 We missed out on actually installing React Navigation, 325 00:18:34,030 --> 00:18:36,500 as I mentioned earlier on. 326 00:18:36,500 --> 00:18:41,180 So to do this, in the slides I said you can use npm. 327 00:18:41,180 --> 00:18:44,590 There's an alternative to npm called Yarn. 328 00:18:44,590 --> 00:18:45,550 I personally prefer it. 329 00:18:45,550 --> 00:18:49,530 It's really up to personal preference here ultimately. 330 00:18:49,530 --> 00:18:55,220 It's fast and it has, in my opinion, some nicer tooling associated with it. 331 00:18:55,220 --> 00:18:57,310 So I'm going to run Yarn add here. 332 00:18:57,310 --> 00:19:07,510 And yarn add react-navigation at 2.0.0-beta.3. 333 00:19:07,510 --> 00:19:12,520 And once that's done, as you can see, it's quite fast. 334 00:19:12,520 --> 00:19:13,955 We can refresh this. 335 00:19:13,955 --> 00:19:19,250 336 00:19:19,250 --> 00:19:21,010 And so we have something here. 337 00:19:21,010 --> 00:19:24,210 We have essentially a pretty useless thing. 338 00:19:24,210 --> 00:19:28,690 But it is being rendered by the Switch Navigator. 339 00:19:28,690 --> 00:19:35,410 Now, to demonstrate actually some useful behavior here, 340 00:19:35,410 --> 00:19:37,970 let's just copy and paste this screen component 341 00:19:37,970 --> 00:19:40,990 and create ScreenComponentTwo. 342 00:19:40,990 --> 00:19:43,510 I'm going to give it a different border color. 343 00:19:43,510 --> 00:19:49,240 And I'm going to make it say, "Go to screen one." 344 00:19:49,240 --> 00:19:54,640 Lastly, I'm going to add an onPress function here, 345 00:19:54,640 --> 00:19:56,980 so that when you press on the button, we're 346 00:19:56,980 --> 00:20:01,241 going to navigate to the second screen from the first screen. 347 00:20:01,241 --> 00:20:03,490 And then I'll add the same thing to the second screen, 348 00:20:03,490 --> 00:20:06,490 so that when we press on it, we go back to the first screen. 349 00:20:06,490 --> 00:20:10,690 So you might might remember from the previous slide, 350 00:20:10,690 --> 00:20:13,377 we do navigation.navigate. 351 00:20:13,377 --> 00:20:15,460 And we currently haven't defined a route for this, 352 00:20:15,460 --> 00:20:18,160 but we'll just call it RouteNameTwo. 353 00:20:18,160 --> 00:20:23,080 And this similar thing can be done down here. 354 00:20:23,080 --> 00:20:25,730 355 00:20:25,730 --> 00:20:29,150 Except as per the title, "Go to screen one," 356 00:20:29,150 --> 00:20:33,160 we're going to send it to RouteNameOne. 357 00:20:33,160 --> 00:20:34,400 Now I can just change these. 358 00:20:34,400 --> 00:20:39,130 359 00:20:39,130 --> 00:20:41,690 And you can see, when we press on these buttons, 360 00:20:41,690 --> 00:20:45,320 we are switching from one screen to the other. 361 00:20:45,320 --> 00:20:49,600 So this is the most simplistic navigator possible, essentially. 362 00:20:49,600 --> 00:20:54,340 Only show one screen at a time, and we can switch between the various screens 363 00:20:54,340 --> 00:20:56,067 that we have in the Navigator. 364 00:20:56,067 --> 00:20:58,900 This might look kind of familiar to you, because this is essentially 365 00:20:58,900 --> 00:21:01,750 what is happening in the Contact List example. 366 00:21:01,750 --> 00:21:07,240 When you press Add Contact, we're setting some state on the app component 367 00:21:07,240 --> 00:21:09,330 to say, we are now showing the form. 368 00:21:09,330 --> 00:21:12,260 So we toggle showForm from false to true. 369 00:21:12,260 --> 00:21:15,490 And we stop rendering the list of contacts, 370 00:21:15,490 --> 00:21:19,120 and we start rendering the Contact Form. 371 00:21:19,120 --> 00:21:23,450 And this is the same sort of pattern, but in a more structured sort 372 00:21:23,450 --> 00:21:23,950 of approach. 373 00:21:23,950 --> 00:21:26,020 That hopefully as we continue, you'll start 374 00:21:26,020 --> 00:21:29,680 to see the benefits of what may seem like a little bit more complexity 375 00:21:29,680 --> 00:21:31,470 up front. 376 00:21:31,470 --> 00:21:37,025 But let's go ahead and convert the example that we have-- 377 00:21:37,025 --> 00:21:39,220 let's see where we are here. 378 00:21:39,220 --> 00:21:42,880 Yeah, let's convert the example to use a Switch Navigator. 379 00:21:42,880 --> 00:21:43,380 Right? 380 00:21:43,380 --> 00:21:45,310 So we have that right now. 381 00:21:45,310 --> 00:21:47,330 We're going to keep it to look exactly the same, 382 00:21:47,330 --> 00:21:50,630 but the only difference is the underlying implementation, 383 00:21:50,630 --> 00:21:52,840 we use a Switch Navigator. 384 00:21:52,840 --> 00:21:54,110 So let's go back here. 385 00:21:54,110 --> 00:21:56,304 We don't need this anymore. 386 00:21:56,304 --> 00:21:59,470 I'm going to uncomment the whole app. 387 00:21:59,470 --> 00:22:03,850 And current implementation, right. 388 00:22:03,850 --> 00:22:05,320 setState. 389 00:22:05,320 --> 00:22:09,490 And we want to toggle contacts in that showForm. 390 00:22:09,490 --> 00:22:11,200 So that's state showForm true. 391 00:22:11,200 --> 00:22:12,866 So we're not going to need that anymore. 392 00:22:12,866 --> 00:22:16,460 But there are a few things we need to do first to get prepared for this. 393 00:22:16,460 --> 00:22:21,040 I'm going to pull out these components, that are implicitly 394 00:22:21,040 --> 00:22:24,880 sort of screens inside of the app, into separate components that I'm just 395 00:22:24,880 --> 00:22:26,950 going to add a suffix of screen to. 396 00:22:26,950 --> 00:22:30,520 And that's just the convention that is very common 397 00:22:30,520 --> 00:22:33,170 when structuring these applications. 398 00:22:33,170 --> 00:22:36,190 So I'm going to make a screens directory, 399 00:22:36,190 --> 00:22:39,270 and then I'm going to create a-- 400 00:22:39,270 --> 00:22:39,770 let's see. 401 00:22:39,770 --> 00:22:40,280 Yeah. 402 00:22:40,280 --> 00:22:53,010 AddContactScreen, and-- that actually has to be in the screens directory. 403 00:22:53,010 --> 00:22:56,896 And I'm going to create a Contact List screen. 404 00:22:56,896 --> 00:22:59,860 Screens, Contact. 405 00:22:59,860 --> 00:23:03,429 406 00:23:03,429 --> 00:23:05,720 So this is just a matter of shuffling stuff around now. 407 00:23:05,720 --> 00:23:07,880 We no longer need showForm. 408 00:23:07,880 --> 00:23:12,667 We'll leave showContacts there for now, but it's days are numbered. 409 00:23:12,667 --> 00:23:14,000 And we're going to rip this out. 410 00:23:14,000 --> 00:23:15,790 So AddContactForm. 411 00:23:15,790 --> 00:23:18,010 I'll start with this one. 412 00:23:18,010 --> 00:23:25,512 Go into screens, AddContactScreen, and AddContactForm. 413 00:23:25,512 --> 00:23:28,784 Put that one in here, as well. 414 00:23:28,784 --> 00:23:37,560 And in fact, why don't I just copy this from an already completed version 415 00:23:37,560 --> 00:23:38,992 of that. 416 00:23:38,992 --> 00:23:40,960 There we go. 417 00:23:40,960 --> 00:23:46,650 So, all I did there was import the AddContactForm, 418 00:23:46,650 --> 00:23:52,060 and then move some behavior here, which we'll explain this line in a moment. 419 00:23:52,060 --> 00:23:53,470 So I'll comment that out. 420 00:23:53,470 --> 00:23:57,600 But essentially just render the form and pass some sort of submit function 421 00:23:57,600 --> 00:23:58,530 through. 422 00:23:58,530 --> 00:24:04,793 I'm going to do the same thing now with the list screen. 423 00:24:04,793 --> 00:24:07,530 I'm going to go over here, just copy that in. 424 00:24:07,530 --> 00:24:10,620 425 00:24:10,620 --> 00:24:14,430 So ContactListScreen is essentially just all of the logic 426 00:24:14,430 --> 00:24:20,190 that we had inside of the app component previously of toggleContacts. 427 00:24:20,190 --> 00:24:22,530 Some state about whether we're showing the contacts. 428 00:24:22,530 --> 00:24:27,670 We have a SectionListContacts component that is rendered down here. 429 00:24:27,670 --> 00:24:30,670 We just don't maintain the showForm state anymore. 430 00:24:30,670 --> 00:24:35,420 Instead, when you press showForm, we navigate to the AddContact route. 431 00:24:35,420 --> 00:24:38,240 432 00:24:38,240 --> 00:24:40,300 So let's go back to the app. 433 00:24:40,300 --> 00:24:42,640 We have a good amount of stuff we can delete here. 434 00:24:42,640 --> 00:24:45,170 This all now lives outside of the app component. 435 00:24:45,170 --> 00:24:47,650 It's inside of the ContactListScreen. 436 00:24:47,650 --> 00:24:50,110 So we can remove that. 437 00:24:50,110 --> 00:24:55,750 And we can remove various other things. toggleContacts is now 438 00:24:55,750 --> 00:24:57,550 in the other component. 439 00:24:57,550 --> 00:24:59,740 sort is unused. 440 00:24:59,740 --> 00:25:03,940 showForm is not used here. 441 00:25:03,940 --> 00:25:08,330 Instead, we need to render something here. 442 00:25:08,330 --> 00:25:09,580 Rather, return something here. 443 00:25:09,580 --> 00:25:12,340 444 00:25:12,340 --> 00:25:16,060 And that needs to be our Switch Navigator. 445 00:25:16,060 --> 00:25:26,920 So let's add a createSwitchNavigator from react-navigation. 446 00:25:26,920 --> 00:25:34,760 And it was-- let's check the name of that. 447 00:25:34,760 --> 00:25:38,830 It was AddContact, was the name of our route. 448 00:25:38,830 --> 00:25:41,230 And it was AddContactScreen. 449 00:25:41,230 --> 00:25:43,840 450 00:25:43,840 --> 00:25:46,244 And then there was-- 451 00:25:46,244 --> 00:25:47,660 what was that referred to as here? 452 00:25:47,660 --> 00:25:55,860 453 00:25:55,860 --> 00:25:58,908 ContactList will be ContactListScreen. 454 00:25:58,908 --> 00:26:01,600 455 00:26:01,600 --> 00:26:06,100 And we want the app to start off as being on the Contact List screen, 456 00:26:06,100 --> 00:26:08,200 and not on the Add Contact screen. 457 00:26:08,200 --> 00:26:11,890 So I'm just going to have this other parameter here, initialRouteName, 458 00:26:11,890 --> 00:26:15,970 and say ContactList. 459 00:26:15,970 --> 00:26:22,240 Now, if we, just like that, scroll right down, and render AppNavigator. 460 00:26:22,240 --> 00:26:26,320 461 00:26:26,320 --> 00:26:28,480 We have a missing import. 462 00:26:28,480 --> 00:26:32,072 Of course, we need to import AddContactScreen 463 00:26:32,072 --> 00:26:36,690 from screens, AddContactScreen. 464 00:26:36,690 --> 00:26:47,135 And we need to import ContactListScreen from ContactListScreen. 465 00:26:47,135 --> 00:26:50,940 466 00:26:50,940 --> 00:26:51,580 OK. 467 00:26:51,580 --> 00:26:52,390 That's good. 468 00:26:52,390 --> 00:26:55,830 So let's pop right in here. 469 00:26:55,830 --> 00:27:01,400 Screen, props-- I'm just going to render an empty view here for now, 470 00:27:01,400 --> 00:27:04,610 so we at least have something showing up. 471 00:27:04,610 --> 00:27:09,289 And the problem here is that currently, the way that it worked 472 00:27:09,289 --> 00:27:11,080 is, when it all lived inside one component, 473 00:27:11,080 --> 00:27:13,900 it was very clear where our contacts state lived. 474 00:27:13,900 --> 00:27:19,000 It was simply a state inside of the app, which we passed in as a prop 475 00:27:19,000 --> 00:27:26,230 to our Contact List, and that we updated by calling addContact on the app, which 476 00:27:26,230 --> 00:27:27,580 then updated the state. 477 00:27:27,580 --> 00:27:30,310 It's a little bit different when we have something 478 00:27:30,310 --> 00:27:34,870 like this, where we're returning an AppNavigator component, which 479 00:27:34,870 --> 00:27:37,960 in turn then renders our Contact List screen. 480 00:27:37,960 --> 00:27:43,600 So we need some way to say, pass this prop through 481 00:27:43,600 --> 00:27:48,650 to the screens inside of the application. 482 00:27:48,650 --> 00:27:52,480 And for that, there's something called screen props. 483 00:27:52,480 --> 00:27:58,030 So, if you specify screen props, you're able to pass in an object 484 00:27:58,030 --> 00:28:04,540 where that object is passed into every screen component in the navigator. 485 00:28:04,540 --> 00:28:07,660 So it's a little caveat there. 486 00:28:07,660 --> 00:28:11,000 It's very good for prototyping, and for examples like this. 487 00:28:11,000 --> 00:28:15,910 However, as you will learn in the performance lecture later on, 488 00:28:15,910 --> 00:28:17,710 there are better ways to do this. 489 00:28:17,710 --> 00:28:20,410 And you'll talk a little bit about Redux later on. 490 00:28:20,410 --> 00:28:23,530 And so this is just generally a potentially useful escape 491 00:28:23,530 --> 00:28:26,110 hatch that you can use in prototypes and such. 492 00:28:26,110 --> 00:28:28,940 But I wouldn't count on it in a large application. 493 00:28:28,940 --> 00:28:30,550 It's perfectly fine here, though. 494 00:28:30,550 --> 00:28:33,880 So the way this works is that we pass in some screen props 495 00:28:33,880 --> 00:28:35,862 to the top level navigator. 496 00:28:35,862 --> 00:28:37,570 And then inside of our screen components, 497 00:28:37,570 --> 00:28:40,420 we say this.props.screenProps dot whatever 498 00:28:40,420 --> 00:28:43,940 the thing is that we want to access. 499 00:28:43,940 --> 00:28:55,310 So here what we want to access is, we want contacts, which is here. 500 00:28:55,310 --> 00:28:58,572 501 00:28:58,572 --> 00:28:59,510 All right. 502 00:28:59,510 --> 00:29:02,940 So let's go back to Contact List. 503 00:29:02,940 --> 00:29:09,140 So as you can see, we're passing in the SectionListContacts based off 504 00:29:09,140 --> 00:29:11,990 of this.props.screenProps.contacts. 505 00:29:11,990 --> 00:29:14,420 So unless there's a typo that should work. 506 00:29:14,420 --> 00:29:16,430 And there we go. 507 00:29:16,430 --> 00:29:19,320 And we can navigate to this screen. 508 00:29:19,320 --> 00:29:24,170 However, we currently don't have any way of actually updating the contact. 509 00:29:24,170 --> 00:29:31,790 Because previously, we were able to call directly into addContact from the form, 510 00:29:31,790 --> 00:29:37,320 but we're not passing in this prop anymore to the addContact form. 511 00:29:37,320 --> 00:29:40,940 And so we need to use screenProps again to pass this function through. 512 00:29:40,940 --> 00:29:47,036 So we can say, addContact is this.addContact. 513 00:29:47,036 --> 00:29:50,370 And let's format that. 514 00:29:50,370 --> 00:29:57,280 And on AddContactScreen, if I just uncomment that line, 515 00:29:57,280 --> 00:30:00,100 now that should do what we need. 516 00:30:00,100 --> 00:30:06,106 So, let's say, Eric V., 1, 2, 3, 4, 5. 517 00:30:06,106 --> 00:30:08,240 And I hit Submit. 518 00:30:08,240 --> 00:30:08,800 All right. 519 00:30:08,800 --> 00:30:11,930 So that now updates here. 520 00:30:11,930 --> 00:30:14,920 So certainly there are some costs here, in terms 521 00:30:14,920 --> 00:30:17,440 of a little bit of added complexity. 522 00:30:17,440 --> 00:30:20,020 But we have added some structure that now at least 523 00:30:20,020 --> 00:30:22,374 we can continue to grow in our application. 524 00:30:22,374 --> 00:30:25,540 We were quite limited in what we were able to do in the Contact List before, 525 00:30:25,540 --> 00:30:27,640 when it all lived inside of this one component. 526 00:30:27,640 --> 00:30:32,980 Now we have a clear way to add on new screens and jump between those screens 527 00:30:32,980 --> 00:30:36,176 without having to depend on adding some new state every time we 528 00:30:36,176 --> 00:30:37,300 want to add another screen. 529 00:30:37,300 --> 00:30:40,480 530 00:30:40,480 --> 00:30:42,310 All right. 531 00:30:42,310 --> 00:30:45,320 Let's move on then to the next topic. 532 00:30:45,320 --> 00:30:47,590 Next topic is Stack Navigator. 533 00:30:47,590 --> 00:30:51,340 So the Switch Navigator is very primitive in what it can accomplish, 534 00:30:51,340 --> 00:30:53,350 switch from one screen to another. 535 00:30:53,350 --> 00:30:58,000 But typically potentially the most common navigation in mobile apps, 536 00:30:58,000 --> 00:31:02,500 depending on the app, is to tap on some button, 537 00:31:02,500 --> 00:31:04,900 and then have it push some screen on top. 538 00:31:04,900 --> 00:31:07,750 Or, on Android, it kind of fades in from the bottom. 539 00:31:07,750 --> 00:31:10,210 And then there's some Back button available to you, 540 00:31:10,210 --> 00:31:13,420 where you press it in the header and it goes back to the other screen. 541 00:31:13,420 --> 00:31:16,700 And that kind of flow is extremely common. 542 00:31:16,700 --> 00:31:19,150 And of course, we have to provide a solution 543 00:31:19,150 --> 00:31:20,920 for that with React Navigation. 544 00:31:20,920 --> 00:31:23,890 And the way that that works is with something called Stack Navigator. 545 00:31:23,890 --> 00:31:27,940 So it provides the platform-specific layout animations and gestures 546 00:31:27,940 --> 00:31:33,340 that you'd expect from this kind of navigation pattern. 547 00:31:33,340 --> 00:31:37,720 So we get the screen sliding in from right to left. 548 00:31:37,720 --> 00:31:39,397 You can dismiss by swiping. 549 00:31:39,397 --> 00:31:41,230 There are modals that go from bottom to top, 550 00:31:41,230 --> 00:31:44,440 and you can swipe down, and that sort of thing. 551 00:31:44,440 --> 00:31:47,950 You can push items from the stack, you can pop from the stack, 552 00:31:47,950 --> 00:31:50,050 replace the current item, et cetera. 553 00:31:50,050 --> 00:31:53,500 And so it's called Stack, of course, because of its relationship 554 00:31:53,500 --> 00:31:55,700 to the stack data structure. 555 00:31:55,700 --> 00:32:01,974 So if you are curious about conceptually how this data manipulation works, 556 00:32:01,974 --> 00:32:04,390 and you're not familiar with the stack data structure yet, 557 00:32:04,390 --> 00:32:09,370 that's just worth checking out so you get some good mental model for it. 558 00:32:09,370 --> 00:32:11,530 So the Stack Navigator looks something like this. 559 00:32:11,530 --> 00:32:14,890 You press Go to Two, in this case. 560 00:32:14,890 --> 00:32:16,920 The two-screen slides on. 561 00:32:16,920 --> 00:32:19,900 You say Go to Three, third screen slides on. 562 00:32:19,900 --> 00:32:21,900 If you press Back, it goes back. 563 00:32:21,900 --> 00:32:24,370 Swipes, or rather animates, away. 564 00:32:24,370 --> 00:32:26,515 And similar for that one. 565 00:32:26,515 --> 00:32:28,270 So let's push these back on. 566 00:32:28,270 --> 00:32:32,500 And let's see what it looks like actually behind the scenes right now. 567 00:32:32,500 --> 00:32:35,130 Because we knew that, with the Switch Navigator, 568 00:32:35,130 --> 00:32:36,880 when we switch from one screen to another, 569 00:32:36,880 --> 00:32:39,610 we unmount the screen that we switched away from. 570 00:32:39,610 --> 00:32:41,560 It is now no longer rendered. 571 00:32:41,560 --> 00:32:43,850 It is not in memory. 572 00:32:43,850 --> 00:32:47,450 It does not exist as far as our application is concerned. 573 00:32:47,450 --> 00:32:51,630 But in a Stack Navigator, we keep all of these previous routes, 574 00:32:51,630 --> 00:32:53,502 and previous screens, mounted and in memory. 575 00:32:53,502 --> 00:32:54,960 Because we need to have them there. 576 00:32:54,960 --> 00:32:59,380 We need to know when we're three screens deep into the app, 577 00:32:59,380 --> 00:33:01,480 we still need to maintain the scroll position 578 00:33:01,480 --> 00:33:04,840 that we had, for example, in the feed on the first screen. 579 00:33:04,840 --> 00:33:07,556 And we need to be able to show the screen immediately 580 00:33:07,556 --> 00:33:10,180 when we start swiping back from one screen to the other screen. 581 00:33:10,180 --> 00:33:12,940 And so these all need to stay there, and they need to maintain their state. 582 00:33:12,940 --> 00:33:14,898 There can be exceptions that you can customize, 583 00:33:14,898 --> 00:33:17,140 but this is the generic expected behavior. 584 00:33:17,140 --> 00:33:19,900 585 00:33:19,900 --> 00:33:23,680 Creating a Stack Navigator is very similar to Switch. 586 00:33:23,680 --> 00:33:27,770 We simply swap out the word Switch for Stack. 587 00:33:27,770 --> 00:33:31,030 And we have something working. 588 00:33:31,030 --> 00:33:33,427 To go from one screen to another, similarly, we 589 00:33:33,427 --> 00:33:34,510 use the Navigate function. 590 00:33:34,510 --> 00:33:37,520 591 00:33:37,520 --> 00:33:40,680 There is a small difference here in that Stack actually 592 00:33:40,680 --> 00:33:42,970 supports a tracking history. 593 00:33:42,970 --> 00:33:48,810 So when you call goBack, it will pop the topmost screen 594 00:33:48,810 --> 00:33:55,260 from the stack and transition back to the screen before it. 595 00:33:55,260 --> 00:34:01,870 So let's look at how to implement this inside of our example. 596 00:34:01,870 --> 00:34:07,220 We're going to go back to the app, and once again comment all this out. 597 00:34:07,220 --> 00:34:12,360 And I'm just going to add another example here. 598 00:34:12,360 --> 00:34:19,710 This one, of course, will be called Stack touch examples, 1-stack.js. 599 00:34:19,710 --> 00:34:23,100 600 00:34:23,100 --> 00:34:26,820 And it's very similar to our Switch, so I'm just 601 00:34:26,820 --> 00:34:29,940 going to paste in our example to start with. 602 00:34:29,940 --> 00:34:37,050 And switch out the word Switch for Stack. 603 00:34:37,050 --> 00:34:39,880 And let's see what we get. 604 00:34:39,880 --> 00:34:44,639 So now when I press Go to Screen Two, it transitions to the second screen. 605 00:34:44,639 --> 00:34:47,780 When I swipe back like this, we get this kind of gesture. 606 00:34:47,780 --> 00:34:51,250 Or if I press that button, it goes back. 607 00:34:51,250 --> 00:34:54,300 Another way to do it is by just pressing Go to Screen One. 608 00:34:54,300 --> 00:34:59,250 And it just knows that we already have screen one here in our route stack. 609 00:34:59,250 --> 00:35:04,230 And so in order to get to it, we have to pop the top screen and transition back. 610 00:35:04,230 --> 00:35:07,050 611 00:35:07,050 --> 00:35:14,190 So another thing that is very necessary in Stack Navigators 612 00:35:14,190 --> 00:35:21,000 is the ability to customize the UI that surrounds the Stack Navigator. 613 00:35:21,000 --> 00:35:23,520 For example, as you can see here, there's this header. 614 00:35:23,520 --> 00:35:25,120 It has a title. 615 00:35:25,120 --> 00:35:27,540 The title changes depending on the screen that you're on. 616 00:35:27,540 --> 00:35:33,330 You may want to style it in some certain way to say that the color for the title 617 00:35:33,330 --> 00:35:37,290 is a certain color, the bar is a certain color, et cetera. 618 00:35:37,290 --> 00:35:40,530 And so to do that, we have this static property 619 00:35:40,530 --> 00:35:45,270 that we can use on screen components called Navigation Options. 620 00:35:45,270 --> 00:35:48,930 Every navigator has a set of navigation options 621 00:35:48,930 --> 00:35:52,350 that screens can use to configure it. 622 00:35:52,350 --> 00:35:55,260 And you can see the full list for the Stack Navigator 623 00:35:55,260 --> 00:35:57,557 in the documentation linked here. 624 00:35:57,557 --> 00:35:59,640 For now we're just going to look at a few of them. 625 00:35:59,640 --> 00:36:04,140 We're going to start with Header Title, and dig into some styling 626 00:36:04,140 --> 00:36:06,970 there, as well. 627 00:36:06,970 --> 00:36:11,760 So let's go up to ScreenComponentOne, and let's 628 00:36:11,760 --> 00:36:16,320 set a navigationOptions title. 629 00:36:16,320 --> 00:36:22,736 We'll call this one, I think I said "First screen" on the example before. 630 00:36:22,736 --> 00:36:26,880 Let's give it a header title. 631 00:36:26,880 --> 00:36:37,650 And for ScreenComponentTwo, I'll just say "Screen the second." 632 00:36:37,650 --> 00:36:38,150 OK. 633 00:36:38,150 --> 00:36:41,260 So now we see the title, First screen, and as we 634 00:36:41,260 --> 00:36:43,290 go to screen two, Screen the second. 635 00:36:43,290 --> 00:36:48,050 And it's a small device, so it has gone ahead and truncated and ellipsized 636 00:36:48,050 --> 00:36:51,160 the title for us in that case. 637 00:36:51,160 --> 00:36:52,790 And if you go back, it does that. 638 00:36:52,790 --> 00:36:55,370 Similarly, the Back button in this case says 639 00:36:55,370 --> 00:36:58,160 Back, and not the title of the previous screen, 640 00:36:58,160 --> 00:37:01,790 because there's no space to render the full title. 641 00:37:01,790 --> 00:37:04,520 So it takes care of a lot of this nuanced behavior for you, 642 00:37:04,520 --> 00:37:12,830 that users really expect from navigation on iOS and on Android. 643 00:37:12,830 --> 00:37:14,150 Let's style it a bit. 644 00:37:14,150 --> 00:37:24,180 Let's say the tint color here, we'll just make it match the border. 645 00:37:24,180 --> 00:37:28,460 So if I set the tint color, what that impacts is the button color. 646 00:37:28,460 --> 00:37:32,600 So if I had a Back button on the screen, it would become teal. 647 00:37:32,600 --> 00:37:35,210 It also impacts the title and any other thing 648 00:37:35,210 --> 00:37:40,820 that is sort of an element that's rendered on top of the header. 649 00:37:40,820 --> 00:37:47,400 We could set a header background color through headerStyle. 650 00:37:47,400 --> 00:37:49,700 So if I wanted to make this-- 651 00:37:49,700 --> 00:37:51,050 well, it's already quite white. 652 00:37:51,050 --> 00:37:56,202 Let's just say it needs to be a bit more gray for some reason. 653 00:37:56,202 --> 00:37:57,780 Let's do that. 654 00:37:57,780 --> 00:37:58,280 OK. 655 00:37:58,280 --> 00:37:59,220 So that's a bit gray. 656 00:37:59,220 --> 00:38:01,640 It's kind of boring. 657 00:38:01,640 --> 00:38:04,500 We can make it green. 658 00:38:04,500 --> 00:38:06,260 It's not so legible, but you get the idea. 659 00:38:06,260 --> 00:38:09,100 660 00:38:09,100 --> 00:38:11,510 So let's get rid of that. 661 00:38:11,510 --> 00:38:13,460 All right. 662 00:38:13,460 --> 00:38:16,260 Let's continue on then. 663 00:38:16,260 --> 00:38:19,780 Pop right back in. 664 00:38:19,780 --> 00:38:22,520 Another thing that's really important with Stack Navigators 665 00:38:22,520 --> 00:38:26,750 is the ability to pass parameters between routes. 666 00:38:26,750 --> 00:38:31,430 Typically when you render a component in React, you would pass in some data 667 00:38:31,430 --> 00:38:33,470 through props. 668 00:38:33,470 --> 00:38:37,940 But as we've seen already with rendering the navigator at the root of the app, 669 00:38:37,940 --> 00:38:40,130 we have to use some other kind of construct, 670 00:38:40,130 --> 00:38:46,390 because the navigator itself handles rendering the components for us. 671 00:38:46,390 --> 00:38:49,340 And so, because we don't have the capacity here 672 00:38:49,340 --> 00:38:52,730 to even say pass in some screen props to this next screen, 673 00:38:52,730 --> 00:38:57,790 there is this concept of passing parameters to different routes. 674 00:38:57,790 --> 00:39:00,470 This is very similar, if you've used the web before, 675 00:39:00,470 --> 00:39:03,020 to the idea of query parameters on a route. 676 00:39:03,020 --> 00:39:05,450 So you can add a question mark to the end of a URL, 677 00:39:05,450 --> 00:39:07,480 and say this value is this, and this is that. 678 00:39:07,480 --> 00:39:09,790 It's the same sort of idea. 679 00:39:09,790 --> 00:39:12,320 And so there are several approaches for how 680 00:39:12,320 --> 00:39:15,350 you can manage passing parameters in. 681 00:39:15,350 --> 00:39:19,920 682 00:39:19,920 --> 00:39:23,000 The first one is to pass in a second argument 683 00:39:23,000 --> 00:39:26,540 to the Navigate function, which is an object where 684 00:39:26,540 --> 00:39:33,140 the key is the name of the param, and the value is the value of the param. 685 00:39:33,140 --> 00:39:36,260 You can also update the params for a given route 686 00:39:36,260 --> 00:39:40,806 by calling setParams, and the same sort of syntax for that. 687 00:39:40,806 --> 00:39:42,680 And when you actually want to read the param, 688 00:39:42,680 --> 00:39:46,310 you call getParam, and pass in the name of it. 689 00:39:46,310 --> 00:39:48,840 And optionally, you can pass in a default value. 690 00:39:48,840 --> 00:39:53,080 So if it isn't provided, you fall back to some other value. 691 00:39:53,080 --> 00:39:57,410 So we'll take a look at what this looks like here. 692 00:39:57,410 --> 00:39:59,980 There we go. 693 00:39:59,980 --> 00:40:08,560 And I'm going to just make a third screen, where the third screen is going 694 00:40:08,560 --> 00:40:12,790 to just take a random number, and we're going 695 00:40:12,790 --> 00:40:16,750 to show the random number in our title, and inside of the screen. 696 00:40:16,750 --> 00:40:19,990 So we can demonstrate how you can use the param 697 00:40:19,990 --> 00:40:22,720 in various places in your app. 698 00:40:22,720 --> 00:40:27,880 So this one, I'm just going to mark this as TODO, because we haven't quite 699 00:40:27,880 --> 00:40:29,950 seen how to do that yet. 700 00:40:29,950 --> 00:40:33,170 I'll make a different color here, let's say purple. 701 00:40:33,170 --> 00:40:41,500 And we will just leave this, let's say, let's just make this one "Go back." 702 00:40:41,500 --> 00:40:43,390 So goBack. 703 00:40:43,390 --> 00:40:45,910 704 00:40:45,910 --> 00:40:47,770 And let's register the route. 705 00:40:47,770 --> 00:40:49,090 So let's say Three. 706 00:40:49,090 --> 00:40:53,830 707 00:40:53,830 --> 00:40:54,330 OK. 708 00:40:54,330 --> 00:40:56,250 So we have ScreenComponentThree. 709 00:40:56,250 --> 00:41:01,270 It has a title Todo, and it doesn't do too much inside of it. 710 00:41:01,270 --> 00:41:03,640 Now we're going to look at the ScreenComponentTwo, 711 00:41:03,640 --> 00:41:11,490 and we're going to change it to pass in, let's say, number is randomNumber. 712 00:41:11,490 --> 00:41:15,594 713 00:41:15,594 --> 00:41:17,760 Of course, there is no function called randomNumber. 714 00:41:17,760 --> 00:41:19,051 Let's just quickly define that. 715 00:41:19,051 --> 00:41:22,130 716 00:41:22,130 --> 00:41:22,970 That can just be-- 717 00:41:22,970 --> 00:41:27,290 718 00:41:27,290 --> 00:41:29,190 so that's a random number between 1 and 10. 719 00:41:29,190 --> 00:41:34,230 720 00:41:34,230 --> 00:41:36,990 So now we've made it so on-- 721 00:41:36,990 --> 00:41:40,340 let's change this one actually. 722 00:41:40,340 --> 00:41:44,730 So the second screen goes to screen three instead of one. 723 00:41:44,730 --> 00:41:49,960 And we navigate to the third screen, and we pass in a param called Number. 724 00:41:49,960 --> 00:41:52,980 So when we want to actually use this param now, 725 00:41:52,980 --> 00:42:01,005 we will add a Text element here, and say this.props.navigation.getParam, number. 726 00:42:01,005 --> 00:42:03,820 727 00:42:03,820 --> 00:42:10,990 And let's make it stand out a bit, and give it a big font size. 728 00:42:10,990 --> 00:42:14,536 And lastly, we know we have to import this component. 729 00:42:14,536 --> 00:42:17,970 730 00:42:17,970 --> 00:42:18,470 Right. 731 00:42:18,470 --> 00:42:19,950 So we have the number 9 there. 732 00:42:19,950 --> 00:42:23,030 If we go back, now we've unmounted that component, 733 00:42:23,030 --> 00:42:26,020 and so if we go back again, as well-- oh, it happened to be 9 734 00:42:26,020 --> 00:42:27,360 this time, also. 735 00:42:27,360 --> 00:42:28,030 There we go. 736 00:42:28,030 --> 00:42:30,090 2. 737 00:42:30,090 --> 00:42:35,410 And so we're passing in random numbers every time we go to that screen. 738 00:42:35,410 --> 00:42:44,720 We can also change this, so we can add another button that says setParams. 739 00:42:44,720 --> 00:42:49,430 And we'll say we're setting the number to another random number. 740 00:42:49,430 --> 00:42:52,210 This one we'll say "New number." 741 00:42:52,210 --> 00:42:56,640 742 00:42:56,640 --> 00:43:00,220 And if you go to screen two and three, you see a 3. 743 00:43:00,220 --> 00:43:03,420 Now we can update that param while we're here. 744 00:43:03,420 --> 00:43:07,050 This isn't particularly useful for changing the param 745 00:43:07,050 --> 00:43:10,800 when we're using it just in the render function of the component. 746 00:43:10,800 --> 00:43:14,010 But it does get very useful, because it's 747 00:43:14,010 --> 00:43:17,100 a very important way for how you can pass 748 00:43:17,100 --> 00:43:20,850 data between the header of your component 749 00:43:20,850 --> 00:43:24,730 and the actual screen component itself. 750 00:43:24,730 --> 00:43:28,440 So there's an alternative way to define navigation options, which 751 00:43:28,440 --> 00:43:29,760 is as a function. 752 00:43:29,760 --> 00:43:36,390 And the function takes in some object with various properties. 753 00:43:36,390 --> 00:43:41,170 The one that's the most important is the navigation object. 754 00:43:41,170 --> 00:43:43,860 So this is the same as the navigation object 755 00:43:43,860 --> 00:43:46,980 that is available inside of the component itself, 756 00:43:46,980 --> 00:43:49,370 when we say this.props.navigation. 757 00:43:49,370 --> 00:43:53,310 And so we know that, since we have that, we can say navigation getParam, 758 00:43:53,310 --> 00:43:57,690 and get the parameter that's passed in, and use it inside of our title. 759 00:43:57,690 --> 00:43:59,010 So I'm going to change this. 760 00:43:59,010 --> 00:44:03,500 So the function has to return an object still. 761 00:44:03,500 --> 00:44:06,960 Before it was an object, now it's a function that returns an object. 762 00:44:06,960 --> 00:44:08,370 And React Navigation just knows. 763 00:44:08,370 --> 00:44:13,050 It says, if this is a function, let's call it and pass these values into it, 764 00:44:13,050 --> 00:44:15,810 and then take the return value, and that will be 765 00:44:15,810 --> 00:44:18,270 the navigation options for this route. 766 00:44:18,270 --> 00:44:28,270 So I'm just going to say number is navigation.getParam number. 767 00:44:28,270 --> 00:44:31,710 And go to screen three. 768 00:44:31,710 --> 00:44:33,990 So you can see that now the number is in the header. 769 00:44:33,990 --> 00:44:35,865 You can imagine this is useful in many cases. 770 00:44:35,865 --> 00:44:38,010 For example, you navigate to a profile screen, 771 00:44:38,010 --> 00:44:43,260 and you might want to have the name of the user whose profile you're 772 00:44:43,260 --> 00:44:46,470 visiting up in the header. 773 00:44:46,470 --> 00:44:54,100 There are really numerous use cases for why you might want to apply this. 774 00:44:54,100 --> 00:44:54,600 All right. 775 00:44:54,600 --> 00:45:00,300 So I think we're in a pretty good spot there with params. 776 00:45:00,300 --> 00:45:05,010 Why don't we go ahead and add a button to the header, as well. 777 00:45:05,010 --> 00:45:10,560 So to do this, we can look back here. 778 00:45:10,560 --> 00:45:12,990 See that there's these two navigation options called 779 00:45:12,990 --> 00:45:17,430 headerLeft and headerRight. 780 00:45:17,430 --> 00:45:19,500 So let's go up there. 781 00:45:19,500 --> 00:45:21,840 And I don't know. 782 00:45:21,840 --> 00:45:24,360 We can add it to screen two. 783 00:45:24,360 --> 00:45:27,664 784 00:45:27,664 --> 00:45:37,390 Let's add-- so we have a title. 785 00:45:37,390 --> 00:45:41,565 Then let's say headerRight, let's just give it a button. 786 00:45:41,565 --> 00:45:52,230 787 00:45:52,230 --> 00:45:59,070 So on the second screen now, we have a button 788 00:45:59,070 --> 00:46:01,090 on the top right that says Press Me. 789 00:46:01,090 --> 00:46:03,510 And when we press it, it just says "pressed." 790 00:46:03,510 --> 00:46:05,916 But we also have access the navigation object. 791 00:46:05,916 --> 00:46:20,860 So if we want to, we could make this say navigation.navigate RouteNameThree. 792 00:46:20,860 --> 00:46:25,270 And let's pass in a not so random number. 793 00:46:25,270 --> 00:46:32,270 Let's pass in 11, which is impossible to get otherwise. 794 00:46:32,270 --> 00:46:32,770 Right? 795 00:46:32,770 --> 00:46:34,880 And now we have 11 there. 796 00:46:34,880 --> 00:46:38,110 And so you can use this to essentially do anything 797 00:46:38,110 --> 00:46:40,030 you can do inside of your Render function. 798 00:46:40,030 --> 00:46:42,970 It's just that the header is a separate component 799 00:46:42,970 --> 00:46:48,410 from the contents that are rendered inside of the actual screen itself. 800 00:46:48,410 --> 00:46:50,770 And so to be able to manipulate those contents, 801 00:46:50,770 --> 00:46:56,110 you need to use the navigation options to specify what the behavior should be. 802 00:46:56,110 --> 00:47:03,700 And also to add components to the various positions in the header, 803 00:47:03,700 --> 00:47:07,360 such as the right or left, which I didn't include here. 804 00:47:07,360 --> 00:47:09,910 By default it's the Back button. 805 00:47:09,910 --> 00:47:12,916 And header title we've specified as a string, 806 00:47:12,916 --> 00:47:14,290 but that can also be a component. 807 00:47:14,290 --> 00:47:18,070 If we wanted to use an image component as the title, 808 00:47:18,070 --> 00:47:21,919 we could just swap out the string there for an image. 809 00:47:21,919 --> 00:47:23,710 We could swap it out for a button, as well. 810 00:47:23,710 --> 00:47:37,250 811 00:47:37,250 --> 00:47:38,890 It doesn't render so pretty there. 812 00:47:38,890 --> 00:47:42,450 It's not measuring it properly, but it's working out well, right? 813 00:47:42,450 --> 00:47:43,990 You can render it in that case. 814 00:47:43,990 --> 00:47:50,080 So you have to be a little bit careful in those situations, but there you go. 815 00:47:50,080 --> 00:47:51,184 Great. 816 00:47:51,184 --> 00:47:54,030 Let's see where we are now. 817 00:47:54,030 --> 00:47:54,530 All right. 818 00:47:54,530 --> 00:47:58,780 Let's take a few minute break, and we'll continue after the break 819 00:47:58,780 --> 00:48:04,040 with integrating the Stack Navigator into the Contact List example. 820 00:48:04,040 --> 00:48:06,040 And then with some other pretty fun stuff around 821 00:48:06,040 --> 00:48:10,190 tabs, and composing navigators together. 822 00:48:10,190 --> 00:48:11,052 We'll end up with-- 823 00:48:11,052 --> 00:48:12,760 hopefully we'll get to the point where we 824 00:48:12,760 --> 00:48:16,940 have a switch with a stack inside of it, or rather 825 00:48:16,940 --> 00:48:20,770 a switch with a tab inside of it with stacks inside of the tab. 826 00:48:20,770 --> 00:48:23,450 So some exciting stuff. 827 00:48:23,450 --> 00:48:24,740 Thanks. 828 00:48:24,740 --> 00:48:25,990 ERIC: All right, welcome back. 829 00:48:25,990 --> 00:48:31,300 And thank you, Brent, for introducing everybody to React Navigation, 830 00:48:31,300 --> 00:48:35,110 covering the Switch Navigator, and teaching 831 00:48:35,110 --> 00:48:37,380 a little bit about the Stack Navigator. 832 00:48:37,380 --> 00:48:41,347 And now I'd like to go dive into the code, straight into the examples, 833 00:48:41,347 --> 00:48:43,180 and we're going to take a look at how we can 834 00:48:43,180 --> 00:48:45,059 put the Stack Navigator to good use. 835 00:48:45,059 --> 00:48:48,100 And hopefully our example app is going to start to feel a little bit more 836 00:48:48,100 --> 00:48:51,170 like an app as we continue hacking on it. 837 00:48:51,170 --> 00:48:53,140 So here's where we we're left with. 838 00:48:53,140 --> 00:48:58,420 We've got our App.js, and we've added a couple of screens. 839 00:48:58,420 --> 00:49:01,990 We've got our App Navigator, which is a Switch Navigator. 840 00:49:01,990 --> 00:49:05,110 And as you can see, we can switch to Add Contact, 841 00:49:05,110 --> 00:49:08,269 and it's just instantly switches over to the form. 842 00:49:08,269 --> 00:49:10,060 But what we'd really like is we'd like more 843 00:49:10,060 --> 00:49:15,460 of a nice, more traditional transition, where it pushes in from the side. 844 00:49:15,460 --> 00:49:17,650 So we can use the Stack Navigator for that. 845 00:49:17,650 --> 00:49:20,200 And the API for the Stack Navigator, as you've already seen, 846 00:49:20,200 --> 00:49:21,970 is really similar to the Switch Navigator. 847 00:49:21,970 --> 00:49:24,340 So we can actually start by just swapping out 848 00:49:24,340 --> 00:49:27,040 the creators for these navigators. 849 00:49:27,040 --> 00:49:31,420 So here where we go into, we're calling createSwitchNavigator, 850 00:49:31,420 --> 00:49:35,080 it's our higher order component that sets up our top level 851 00:49:35,080 --> 00:49:39,017 navigator that we're going to render inside of our app out right here. 852 00:49:39,017 --> 00:49:42,100 But instead of calling that, we're going to just call createStackNavigator 853 00:49:42,100 --> 00:49:42,599 instead. 854 00:49:42,599 --> 00:49:45,920 So I'm actually just going to kind of rename it right here. 855 00:49:45,920 --> 00:49:48,260 And let's see what it looks like inside of our app. 856 00:49:48,260 --> 00:49:49,750 You can see the header appears. 857 00:49:49,750 --> 00:49:53,110 And when we tap Add Contact, it pushes a screen. 858 00:49:53,110 --> 00:49:55,970 And it pushes this form screen that we've got. 859 00:49:55,970 --> 00:49:58,720 Now, it still is not looking super great. 860 00:49:58,720 --> 00:50:01,750 We're going to want to have some things in the header here, 861 00:50:01,750 --> 00:50:05,220 and we're also going to want to add-- 862 00:50:05,220 --> 00:50:07,870 the Add Contact button should actually be in the header, 863 00:50:07,870 --> 00:50:11,240 because that feels a little bit nicer. 864 00:50:11,240 --> 00:50:15,270 So first, let's go ahead and jump into our Contact List 865 00:50:15,270 --> 00:50:19,300 screen and our Add Contact screen, and set up the header. 866 00:50:19,300 --> 00:50:22,540 So our Contact List screen right here, it 867 00:50:22,540 --> 00:50:24,610 doesn't have any navigation options set on it. 868 00:50:24,610 --> 00:50:30,621 But we can go ahead and set up some static navigation options. 869 00:50:30,621 --> 00:50:33,370 And we're going to go ahead and just put on a normal header, which 870 00:50:33,370 --> 00:50:43,000 is via headerTitle of Contacts. 871 00:50:43,000 --> 00:50:49,470 And we're going to want to do the same thing in our Add Contact screen. 872 00:50:49,470 --> 00:50:53,140 We're going to want to have roughly the same sort of navigation options 873 00:50:53,140 --> 00:50:55,870 with Add Contact. 874 00:50:55,870 --> 00:50:57,310 Let's take a look. 875 00:50:57,310 --> 00:50:59,350 Here it says Contacts. 876 00:50:59,350 --> 00:51:01,540 Nice-- Add Contact. 877 00:51:01,540 --> 00:51:05,541 And the Back button is just working out of the box. 878 00:51:05,541 --> 00:51:06,040 All right. 879 00:51:06,040 --> 00:51:10,357 Now let's move this Add Contact button up into the header. 880 00:51:10,357 --> 00:51:12,190 So that would be in the Contact List screen, 881 00:51:12,190 --> 00:51:15,040 because this is where we're going to want it. 882 00:51:15,040 --> 00:51:17,313 So first, of course, we just put a headerRight. 883 00:51:17,313 --> 00:51:20,420 884 00:51:20,420 --> 00:51:24,680 And this is one of these special navigation options 885 00:51:24,680 --> 00:51:27,980 that you can put inside of a stack. 886 00:51:27,980 --> 00:51:31,280 And you can see this link for more details about what else 887 00:51:31,280 --> 00:51:32,072 you can have there. 888 00:51:32,072 --> 00:51:33,946 But our headerRight, in this case, let's just 889 00:51:33,946 --> 00:51:37,160 put a button, which we're going to want to import from React Native. 890 00:51:37,160 --> 00:51:38,390 Or we already are, actually. 891 00:51:38,390 --> 00:51:41,312 892 00:51:41,312 --> 00:51:44,640 So Add. 893 00:51:44,640 --> 00:51:47,000 And let's just have an empty onPress handler right now. 894 00:51:47,000 --> 00:51:53,010 895 00:51:53,010 --> 00:51:54,030 There we go. 896 00:51:54,030 --> 00:51:55,810 So it doesn't do anything. 897 00:51:55,810 --> 00:52:01,500 And remember, we're going to want to call navigation.navigate 898 00:52:01,500 --> 00:52:07,140 to the AddContact route. 899 00:52:07,140 --> 00:52:12,690 It's the route name that we have defined here in the Stack Navigator. 900 00:52:12,690 --> 00:52:15,990 Now, over here, we don't have access to the navigation prop. 901 00:52:15,990 --> 00:52:17,910 And that's because this is a static property 902 00:52:17,910 --> 00:52:19,890 that we're putting on our component. 903 00:52:19,890 --> 00:52:25,130 So we can upgrade that by turning this into a dynamic navigation options, 904 00:52:25,130 --> 00:52:27,120 which is to say that it's a function. 905 00:52:27,120 --> 00:52:30,840 And that function is given an object of things, right? 906 00:52:30,840 --> 00:52:33,420 And we can access things.navigation, which 907 00:52:33,420 --> 00:52:36,026 is what we're doing here by destructuring it. 908 00:52:36,026 --> 00:52:38,400 And what we can do is, we can put parentheses around here 909 00:52:38,400 --> 00:52:40,990 to signify that this is a function that's returning 910 00:52:40,990 --> 00:52:43,660 this object of navigation options. 911 00:52:43,660 --> 00:52:48,030 So now hopefully, our button should have access to navigation.navigate, 912 00:52:48,030 --> 00:52:49,140 and indeed it does. 913 00:52:49,140 --> 00:52:52,511 We can now navigate to our form. 914 00:52:52,511 --> 00:52:55,260 Let's go and delete some of these old buttons that we don't really 915 00:52:55,260 --> 00:52:57,520 need from our Contact List screen. 916 00:52:57,520 --> 00:53:00,316 917 00:53:00,316 --> 00:53:02,650 OK. 918 00:53:02,650 --> 00:53:04,055 Nice. 919 00:53:04,055 --> 00:53:06,430 So now let's make it so that when you click on a contact, 920 00:53:06,430 --> 00:53:09,367 you can actually go into a new Contact Details screen. 921 00:53:09,367 --> 00:53:10,450 That would be really nice. 922 00:53:10,450 --> 00:53:15,240 923 00:53:15,240 --> 00:53:17,730 I'm going to review that in just a second. 924 00:53:17,730 --> 00:53:20,300 So let's go and add a brand new screen here 925 00:53:20,300 --> 00:53:23,250 in our Stack Navigator called ContactDetails. 926 00:53:23,250 --> 00:53:28,150 927 00:53:28,150 --> 00:53:30,350 And we're going to want to import this screen. 928 00:53:30,350 --> 00:53:33,671 We haven't made it yet, but we'll import it from the screens place, 929 00:53:33,671 --> 00:53:34,670 from the screens folder. 930 00:53:34,670 --> 00:53:40,560 931 00:53:40,560 --> 00:53:42,040 OK. 932 00:53:42,040 --> 00:53:45,070 So the ContactDetailsScreen, I'm just going 933 00:53:45,070 --> 00:53:48,670 to jump over here and create that new screen right here. 934 00:53:48,670 --> 00:53:55,450 935 00:53:55,450 --> 00:53:57,910 And I'm going to want to do a little bit of copy/paste 936 00:53:57,910 --> 00:54:03,370 just so that we can kind of get up and running a little faster here. 937 00:54:03,370 --> 00:54:06,490 But this is nothing that you haven't seen before. 938 00:54:06,490 --> 00:54:09,910 All it's going to be is a empty screen. 939 00:54:09,910 --> 00:54:12,830 940 00:54:12,830 --> 00:54:14,060 OK. 941 00:54:14,060 --> 00:54:15,535 Let's take a look. 942 00:54:15,535 --> 00:54:18,160 Well, we actually aren't linking to our Contact Details screen, 943 00:54:18,160 --> 00:54:20,830 even though we've registered the route in the Navigator. 944 00:54:20,830 --> 00:54:22,600 So let's go ahead and do that. 945 00:54:22,600 --> 00:54:26,800 And to do that, you can see here is the Row component 946 00:54:26,800 --> 00:54:29,470 is where we're actually rendering the contact row. 947 00:54:29,470 --> 00:54:32,650 But here we don't have access to this.props.navigation. 948 00:54:32,650 --> 00:54:40,450 But we do have it up here in the ContactListScreen, where we're 949 00:54:40,450 --> 00:54:42,730 rendering the SectionListContacts. 950 00:54:42,730 --> 00:54:44,890 So here we're providing all of the contacts 951 00:54:44,890 --> 00:54:48,190 that we are getting in through our screen props. 952 00:54:48,190 --> 00:54:50,770 And what we can do here is we can add a new handler 953 00:54:50,770 --> 00:54:53,890 for when a contact gets pressed. 954 00:54:53,890 --> 00:55:00,454 So let's say, onSelectContact, we're going to want to do something. 955 00:55:00,454 --> 00:55:03,370 And probably going to want to do something with this.props.navigation. 956 00:55:03,370 --> 00:55:07,720 But first we need to implement this onSelectContact prop inside 957 00:55:07,720 --> 00:55:09,970 of SectionListContacts. 958 00:55:09,970 --> 00:55:14,410 So I'm just going to open that on up. 959 00:55:14,410 --> 00:55:19,270 The Section List is using renderItem to render each row. 960 00:55:19,270 --> 00:55:22,330 And this row renderer here is being declared 961 00:55:22,330 --> 00:55:25,960 outside of our functional component, SectionListContacts. 962 00:55:25,960 --> 00:55:29,380 So we're going to want to access the props that are 963 00:55:29,380 --> 00:55:31,300 being passed into SectionListContacts. 964 00:55:31,300 --> 00:55:36,150 So in this case what we can do is, we're actually going to take this renderItem, 965 00:55:36,150 --> 00:55:39,760 and we're going to bring it inside of our component. 966 00:55:39,760 --> 00:55:42,829 So this way we can define it based on the props. 967 00:55:42,829 --> 00:55:44,620 So what we're going to want to do is, we're 968 00:55:44,620 --> 00:55:46,925 going to want to pass our new prop-- 969 00:55:46,925 --> 00:55:48,360 waht was it called-- 970 00:55:48,360 --> 00:55:51,130 onSelectContact to the row. 971 00:55:51,130 --> 00:55:52,730 So props.onSelectContact. 972 00:55:52,730 --> 00:55:55,810 973 00:55:55,810 --> 00:55:56,770 OK. 974 00:55:56,770 --> 00:55:59,470 So we're rendering the row with the contact item. 975 00:55:59,470 --> 00:56:01,120 We've provided the handler. 976 00:56:01,120 --> 00:56:06,160 Now the row itself isn't currently touchable. 977 00:56:06,160 --> 00:56:07,840 This isn't a button or anything. 978 00:56:07,840 --> 00:56:11,650 And we can make it touchable by replacing 979 00:56:11,650 --> 00:56:13,721 this view with a touchable component. 980 00:56:13,721 --> 00:56:15,470 So I'm just going to use Toucable Opacity. 981 00:56:15,470 --> 00:56:17,080 It's kind of the easiest to use. 982 00:56:17,080 --> 00:56:20,480 983 00:56:20,480 --> 00:56:23,614 And this basically means that you can press this thing, 984 00:56:23,614 --> 00:56:25,280 even though it's still basically a view. 985 00:56:25,280 --> 00:56:27,655 986 00:56:27,655 --> 00:56:30,030 So when the press happens, what we're going to want to do 987 00:56:30,030 --> 00:56:33,120 is, we're going to want to call this.props.onSelectContact. 988 00:56:33,120 --> 00:56:37,360 989 00:56:37,360 --> 00:56:40,650 But we need to specify which contact is being rendered, 990 00:56:40,650 --> 00:56:43,230 or which is being selected and pressed. 991 00:56:43,230 --> 00:56:44,940 And we have that coming in through props. 992 00:56:44,940 --> 00:56:47,187 We have a lot of information coming in through props 993 00:56:47,187 --> 00:56:48,270 about our current contact. 994 00:56:48,270 --> 00:56:54,460 So let's just pass that in over here, and we'll see how we can use that. 995 00:56:54,460 --> 00:56:54,960 OK. 996 00:56:54,960 --> 00:56:58,380 So finally here, we expect that we're going to have a contact coming in 997 00:56:58,380 --> 00:57:00,120 through here. 998 00:57:00,120 --> 00:57:04,620 And now we have the opportunity to access this.props.navigation.navigate, 999 00:57:04,620 --> 00:57:07,360 so we can navigate to our Contact Details screen. 1000 00:57:07,360 --> 00:57:11,070 I'm just going to copy over the call to navigate from there. 1001 00:57:11,070 --> 00:57:14,010 Contact Details. 1002 00:57:14,010 --> 00:57:15,730 Let's see what happens. 1003 00:57:15,730 --> 00:57:16,961 We can tap it. 1004 00:57:16,961 --> 00:57:17,460 Oops. 1005 00:57:17,460 --> 00:57:21,090 We haven't defined the prop all the way down. 1006 00:57:21,090 --> 00:57:24,480 And I think that's probably inside of Row. 1007 00:57:24,480 --> 00:57:28,200 And so we're referring to this.props, and there is no this.props. 1008 00:57:28,200 --> 00:57:30,770 Because it's a stateless functional component, 1009 00:57:30,770 --> 00:57:33,390 props is just coming in through the function. 1010 00:57:33,390 --> 00:57:34,290 OK. 1011 00:57:34,290 --> 00:57:37,470 Now we're not getting any behavior at all. 1012 00:57:37,470 --> 00:57:45,630 And that's because we haven't actually really gotten to this point. 1013 00:57:45,630 --> 00:57:49,740 Let's throw in a debugger right here. 1014 00:57:49,740 --> 00:57:55,850 This is a quick trick that you can use to figure out 1015 00:57:55,850 --> 00:57:57,410 where you arrive in your code. 1016 00:57:57,410 --> 00:58:03,230 1017 00:58:03,230 --> 00:58:06,580 When we tap our contact, we're not reaching our debugger. 1018 00:58:06,580 --> 00:58:11,570 Otherwise, I expect we would have gotten here in Chrome. 1019 00:58:11,570 --> 00:58:15,240 And Chrome has jumped over here. 1020 00:58:15,240 --> 00:58:19,430 So what we can do is, we can put a debugger earlier on. 1021 00:58:19,430 --> 00:58:22,760 For example, our SectionListContacts. 1022 00:58:22,760 --> 00:58:28,390 We're passing through the props.onSelectContact. 1023 00:58:28,390 --> 00:58:30,640 Here we've got the Touchable Opacity. 1024 00:58:30,640 --> 00:58:33,312 We're passing through props.onSelectContact. 1025 00:58:33,312 --> 00:58:35,020 First, I'll put a debugger statement here 1026 00:58:35,020 --> 00:58:38,590 to make sure that we are in fact reaching our button. 1027 00:58:38,590 --> 00:58:39,516 Tap here. 1028 00:58:39,516 --> 00:58:40,016 Aha. 1029 00:58:40,016 --> 00:58:40,720 OK. 1030 00:58:40,720 --> 00:58:43,910 And we can see that props is in fact our contact. 1031 00:58:43,910 --> 00:58:45,940 So let's jump up to the direct parent of Row. 1032 00:58:45,940 --> 00:58:55,950 1033 00:58:55,950 --> 00:59:02,490 And I'm just going to wrap a little shim here, throw the debugger in, 1034 00:59:02,490 --> 00:59:10,122 and hopefully we'll be able to observe, at this point, 1035 00:59:10,122 --> 00:59:11,580 whether or not we're reaching here. 1036 00:59:11,580 --> 00:59:16,970 So we're still running the old code, because we were stopped in the Row. 1037 00:59:16,970 --> 00:59:24,450 We didn't reach onSelectContact of our list. 1038 00:59:24,450 --> 00:59:30,680 So here, SectionListContacts, when we're rendering it, 1039 00:59:30,680 --> 00:59:38,090 I definitely do expect it to be reaching the debugger of our Contacts List 1040 00:59:38,090 --> 00:59:39,170 screen. 1041 00:59:39,170 --> 00:59:42,210 onSelectContact, SectionListContacts, I'm 1042 00:59:42,210 --> 00:59:46,367 going to double check that we're getting it from the right place here. 1043 00:59:46,367 --> 00:59:52,320 1044 00:59:52,320 --> 00:59:52,820 OK. 1045 00:59:52,820 --> 00:59:55,410 Well this does look like the right thing. 1046 00:59:55,410 --> 00:59:57,600 So I've got my debugger statement here. 1047 00:59:57,600 --> 01:00:01,212 And I'm hoping to reach this top level breakpoint. 1048 01:00:01,212 --> 01:00:03,810 1049 01:00:03,810 --> 01:00:04,660 OK. 1050 01:00:04,660 --> 01:00:05,810 So here we're reaching it. 1051 01:00:05,810 --> 01:00:08,110 And now we can see that we have made it here. 1052 01:00:08,110 --> 01:00:12,400 We've got this.props.navigation. 1053 01:00:12,400 --> 01:00:16,210 And we're calling dot navigate with Contact Details. 1054 01:00:16,210 --> 01:00:20,500 Let's double check to make sure that we've registered this correctly. 1055 01:00:20,500 --> 01:00:22,829 And I can see now that I haven't saved my App file. 1056 01:00:22,829 --> 01:00:25,870 That seems to have been the issue that was preventing us from navigating. 1057 01:00:25,870 --> 01:00:29,350 So now we tap it, we reach our breakpoint, I hit Play, 1058 01:00:29,350 --> 01:00:32,120 and it's gone and navigated to our new screen. 1059 01:00:32,120 --> 01:00:39,220 So this is a little bit of a live debugging adventure, when we figure out 1060 01:00:39,220 --> 01:00:42,400 how to avoid these things. 1061 01:00:42,400 --> 01:00:44,810 Step one is to save your files. 1062 01:00:44,810 --> 01:00:46,090 OK. 1063 01:00:46,090 --> 01:00:49,240 So we're navigating getting to our Contact screen. 1064 01:00:49,240 --> 01:00:52,990 But unfortunately, the header is not looking very good, 1065 01:00:52,990 --> 01:00:56,140 and we actually aren't even passing any information about the contact 1066 01:00:56,140 --> 01:00:58,090 that we've navigated to. 1067 01:00:58,090 --> 01:01:01,670 So the way we can do that is by passing params. 1068 01:01:01,670 --> 01:01:04,420 So when we pass params here, we can pass an arbitrary object 1069 01:01:04,420 --> 01:01:09,700 of various pieces of information, like contact dot phone number. 1070 01:01:09,700 --> 01:01:16,780 1071 01:01:16,780 --> 01:01:19,450 And we can also provide the name. 1072 01:01:19,450 --> 01:01:25,760 1073 01:01:25,760 --> 01:01:28,520 And then inside of our Contact Details screen, 1074 01:01:28,520 --> 01:01:32,480 we can get the param by calling this.props.navigation.getParam. 1075 01:01:32,480 --> 01:01:38,640 1076 01:01:38,640 --> 01:01:43,680 And we're going to want to get the number here, so phone. 1077 01:01:43,680 --> 01:01:46,867 Or do I call it number? 1078 01:01:46,867 --> 01:01:47,700 Let's call it phone. 1079 01:01:47,700 --> 01:01:52,370 1080 01:01:52,370 --> 01:01:52,870 OK. 1081 01:01:52,870 --> 01:01:55,340 So it's displaying the number of our contact. 1082 01:01:55,340 --> 01:01:58,570 And the other thing is, up in the header we want to be able to get the param, 1083 01:01:58,570 --> 01:02:00,055 as well. 1084 01:02:00,055 --> 01:02:01,930 That's the header of our Contact List screen. 1085 01:02:01,930 --> 01:02:05,020 But we can also share the header of our Details 1086 01:02:05,020 --> 01:02:06,820 screen that we haven't really configured. 1087 01:02:06,820 --> 01:02:12,460 So we're going to create a static navigation options, 1088 01:02:12,460 --> 01:02:14,710 and we're going to need access to the navigation prop. 1089 01:02:14,710 --> 01:02:16,876 So this is going to be a dynamic navigation options, 1090 01:02:16,876 --> 01:02:20,050 where we get access to navigation. 1091 01:02:20,050 --> 01:02:24,250 And we're going to want to return an object of options, including 1092 01:02:24,250 --> 01:02:26,460 headerRight. 1093 01:02:26,460 --> 01:02:30,560 Or, sorry, in this case, it's just the headerTitle, 1094 01:02:30,560 --> 01:02:38,200 which we're going to want to grab from navigation.getParam name. 1095 01:02:38,200 --> 01:02:41,450 1096 01:02:41,450 --> 01:02:44,660 So we tap here, and we're able to see our contact. 1097 01:02:44,660 --> 01:02:47,480 Now we also have this button that says "Go to random contact." 1098 01:02:47,480 --> 01:02:51,020 And the idea here is, you might want to be able to link to other contacts, 1099 01:02:51,020 --> 01:02:55,530 maybe to see the contact's sister or parents. 1100 01:02:55,530 --> 01:03:00,785 So in this case, what we can do is we can implement our goToRandom method. 1101 01:03:00,785 --> 01:03:03,690 It should be pretty straightforward. 1102 01:03:03,690 --> 01:03:07,250 Now, goToRandom, the first thing we're going to need to do 1103 01:03:07,250 --> 01:03:09,890 is actually get access to a random contact. 1104 01:03:09,890 --> 01:03:11,960 Now, we have our contacts coming in through 1105 01:03:11,960 --> 01:03:13,910 this.props.screenProps.contacts. 1106 01:03:13,910 --> 01:03:16,940 1107 01:03:16,940 --> 01:03:19,700 So I'm going to go ahead and grab a little bit of logic 1108 01:03:19,700 --> 01:03:22,680 that we're going to use to find a random contact. 1109 01:03:22,680 --> 01:03:25,850 You don't have to look at this too closely, because it's kind of ugly 1110 01:03:25,850 --> 01:03:27,350 code, actually. 1111 01:03:27,350 --> 01:03:32,210 So we're just going to grab the contacts from this.props.screenProps.contacts. 1112 01:03:32,210 --> 01:03:36,050 1113 01:03:36,050 --> 01:03:38,970 And the phone is going to be coming from the param 1114 01:03:38,970 --> 01:03:40,680 as you can see what we do up here. 1115 01:03:40,680 --> 01:03:43,580 I'm just going to copy that right here. 1116 01:03:43,580 --> 01:03:47,150 Except here we're accessing navigation. 1117 01:03:47,150 --> 01:03:48,200 OK. 1118 01:03:48,200 --> 01:03:52,120 So this.props.navigation.getParam for the phone number. 1119 01:03:52,120 --> 01:03:55,370 And then what we can do here is, we're going to have access to random contact. 1120 01:03:55,370 --> 01:03:58,150 I'm just going to put a debugger statement here, 1121 01:03:58,150 --> 01:04:01,630 just so that we can see what happens when we get to this point. 1122 01:04:01,630 --> 01:04:06,084 Hit "Go to random contact," and hopefully we 1123 01:04:06,084 --> 01:04:07,250 get stopped in the debugger. 1124 01:04:07,250 --> 01:04:10,710 1125 01:04:10,710 --> 01:04:11,210 No contacts. 1126 01:04:11,210 --> 01:04:12,841 AUDIENCE: [INAUDIBLE] 1127 01:04:12,841 --> 01:04:13,800 ERIC: That's right. 1128 01:04:13,800 --> 01:04:18,026 So it's a little bit confusing, because we're actually stalling in this 1129 01:04:18,026 --> 01:04:18,900 While loop right now. 1130 01:04:18,900 --> 01:04:21,640 That's why I was saying this code is kind of bad. 1131 01:04:21,640 --> 01:04:29,099 So we have this Contacts file, which generates our content, in this case, 1132 01:04:29,099 --> 01:04:30,390 we're only getting one contact. 1133 01:04:30,390 --> 01:04:35,560 So when we try to get another random one, it's not going so smoothly. 1134 01:04:35,560 --> 01:04:36,060 OK. 1135 01:04:36,060 --> 01:04:37,770 Now we've got multiple contacts. 1136 01:04:37,770 --> 01:04:41,700 And when we tap "Go to random contact," we get here to our debugger. 1137 01:04:41,700 --> 01:04:43,800 And let's take a look at randomContact. 1138 01:04:43,800 --> 01:04:46,191 It's probably an object with name and phone number. 1139 01:04:46,191 --> 01:04:46,690 Great. 1140 01:04:46,690 --> 01:04:52,080 So let's go ahead and navigate to another Contact 1141 01:04:52,080 --> 01:04:53,280 screen on Contact Details. 1142 01:04:53,280 --> 01:05:04,120 So this.props.navigation.navigate to ContactDetails. 1143 01:05:04,120 --> 01:05:06,720 And we're going to want to pass the same information in. 1144 01:05:06,720 --> 01:05:11,784 So we have the name, which is the randomContact.name. 1145 01:05:11,784 --> 01:05:13,700 And we're also going to have the phone number. 1146 01:05:13,700 --> 01:05:17,790 1147 01:05:17,790 --> 01:05:18,920 OK. 1148 01:05:18,920 --> 01:05:21,924 So let's see what happens here. 1149 01:05:21,924 --> 01:05:23,590 We're going to tap on our first contact. 1150 01:05:23,590 --> 01:05:26,420 We're going to tap "Go to random contact." 1151 01:05:26,420 --> 01:05:27,530 Oh, that's strange. 1152 01:05:27,530 --> 01:05:30,710 I expected to navigate to a new screen. 1153 01:05:30,710 --> 01:05:32,469 Well, it turns out that we don't actually 1154 01:05:32,469 --> 01:05:34,760 need to navigate to a new screen, because we're already 1155 01:05:34,760 --> 01:05:36,860 on Contact Details. 1156 01:05:36,860 --> 01:05:40,070 So we called navigate to Contact Details with setting params, 1157 01:05:40,070 --> 01:05:41,910 we provided these additional params. 1158 01:05:41,910 --> 01:05:43,743 But what we're actually doing is, we're just 1159 01:05:43,743 --> 01:05:45,860 setting the params on the current route, which 1160 01:05:45,860 --> 01:05:47,820 is not exactly what we were going for. 1161 01:05:47,820 --> 01:05:52,400 So instead, we can use this other prop that's 1162 01:05:52,400 --> 01:05:58,840 on the navigation prop, called Push. 1163 01:05:58,840 --> 01:06:02,190 Now, Push is always going to push a new screen, 1164 01:06:02,190 --> 01:06:04,340 and you can also provide params to Push. 1165 01:06:04,340 --> 01:06:07,720 So Navigate is going to navigate to your current route 1166 01:06:07,720 --> 01:06:10,550 as identified by your route name. 1167 01:06:10,550 --> 01:06:11,050 All right. 1168 01:06:11,050 --> 01:06:14,140 So let's go ahead and change this Navigate to Push. 1169 01:06:14,140 --> 01:06:16,720 1170 01:06:16,720 --> 01:06:17,380 OK. 1171 01:06:17,380 --> 01:06:19,010 So we tap on one contact. 1172 01:06:19,010 --> 01:06:19,510 We see it. 1173 01:06:19,510 --> 01:06:21,500 We go to another contact. 1174 01:06:21,500 --> 01:06:23,290 And we go to all of our random contacts. 1175 01:06:23,290 --> 01:06:25,810 This is great. 1176 01:06:25,810 --> 01:06:31,840 Now, the Push is only available inside of a Stack Navigator. 1177 01:06:31,840 --> 01:06:37,120 And there are a few other things that are specific to a Stack Navigator. 1178 01:06:37,120 --> 01:06:39,350 Don't mind me while I rearrange this screen. 1179 01:06:39,350 --> 01:06:42,350 1180 01:06:42,350 --> 01:06:45,760 So there's other things like Push, which adds a new screen. 1181 01:06:45,760 --> 01:06:48,450 Pop takes you to the previous screen inside of the stack. 1182 01:06:48,450 --> 01:06:51,580 PopToTop takes you to the top screen inside the stack. 1183 01:06:51,580 --> 01:06:55,030 And Replace is like what we were just doing by accident with the Navigate 1184 01:06:55,030 --> 01:06:57,650 functionality. 1185 01:06:57,650 --> 01:07:00,370 Now, let's talk about composing navigators. 1186 01:07:00,370 --> 01:07:02,590 This is a pretty powerful technique that allows 1187 01:07:02,590 --> 01:07:07,840 you to put one whole navigator visually inside of another. 1188 01:07:07,840 --> 01:07:10,616 Now, you'll get a better intuition for this 1189 01:07:10,616 --> 01:07:12,490 as we move forward, about when you want to be 1190 01:07:12,490 --> 01:07:15,070 putting a navigator inside of another. 1191 01:07:15,070 --> 01:07:17,920 But generally, if you see a header on the screen, 1192 01:07:17,920 --> 01:07:20,702 but you also see a bar on the screen at the same time, 1193 01:07:20,702 --> 01:07:22,660 then that's a case when one of these navigators 1194 01:07:22,660 --> 01:07:24,250 is actually inside of the other. 1195 01:07:24,250 --> 01:07:26,140 And you'll notice that by switching tabs, 1196 01:07:26,140 --> 01:07:29,440 you'll often move away from the whole header. 1197 01:07:29,440 --> 01:07:33,280 Or, it could be composed the other direction. 1198 01:07:33,280 --> 01:07:35,740 Now, the way that we do this is, we actually 1199 01:07:35,740 --> 01:07:39,404 register a navigator as the screen component of another navigator. 1200 01:07:39,404 --> 01:07:42,070 And you should always be careful to make sure that your app only 1201 01:07:42,070 --> 01:07:44,440 has one top-level navigator. 1202 01:07:44,440 --> 01:07:47,170 And the really great thing about composing navigators 1203 01:07:47,170 --> 01:07:50,710 is that you can navigate pretty effortlessly between all of them. 1204 01:07:50,710 --> 01:07:53,170 So if you just use the Navigate functionality, 1205 01:07:53,170 --> 01:07:56,530 and you refer to a route name that's inside of another navigator, 1206 01:07:56,530 --> 01:07:58,870 you'll automatically get over there. 1207 01:07:58,870 --> 01:08:01,662 And goBack also works between different navigators, 1208 01:08:01,662 --> 01:08:04,120 and that's really essential for supporting the Android Back 1209 01:08:04,120 --> 01:08:06,880 button so that the user can always get back, 1210 01:08:06,880 --> 01:08:11,600 even if they're inside of a deeper navigator in the app. 1211 01:08:11,600 --> 01:08:12,580 Cool. 1212 01:08:12,580 --> 01:08:14,980 So this is what it looks like to compose a navigator. 1213 01:08:14,980 --> 01:08:18,910 You can see that, in this case, we're creating a stack navigator as per usual 1214 01:08:18,910 --> 01:08:21,140 with two screen components. 1215 01:08:21,140 --> 01:08:24,257 But then down here when we're creating a Switch Navigator-- 1216 01:08:24,257 --> 01:08:26,090 it's our top-level navigator as you can see, 1217 01:08:26,090 --> 01:08:30,160 because it's an App Navigator-- we're registering the Stack Navigator 1218 01:08:30,160 --> 01:08:33,080 inside of it as the main route. 1219 01:08:33,080 --> 01:08:35,950 1220 01:08:35,950 --> 01:08:36,670 All right. 1221 01:08:36,670 --> 01:08:40,720 So like I said earlier, just one gotcha you should really be careful about 1222 01:08:40,720 --> 01:08:44,470 is to never render a navigator inside of a screen like this. 1223 01:08:44,470 --> 01:08:49,810 You only ever want to render a navigator by itself at the top level. 1224 01:08:49,810 --> 01:08:53,452 And you always want to make sure that the navigators are linked together 1225 01:08:53,452 --> 01:08:55,660 inside the higher order components like you see here. 1226 01:08:55,660 --> 01:08:58,760 1227 01:08:58,760 --> 01:08:59,260 Cool. 1228 01:08:59,260 --> 01:09:03,100 So let's go ahead and put our Stack Navigator that we just 1229 01:09:03,100 --> 01:09:07,640 made inside of a new navigator. 1230 01:09:07,640 --> 01:09:08,140 All right. 1231 01:09:08,140 --> 01:09:11,529 So we can create a brand new navigator here. 1232 01:09:11,529 --> 01:09:15,250 Instead of this App Navigator, let's call it the Main Navigator. 1233 01:09:15,250 --> 01:09:17,950 1234 01:09:17,950 --> 01:09:19,779 And that's a Stack Navigator. 1235 01:09:19,779 --> 01:09:22,294 Now let's create a new App Navigator. 1236 01:09:22,294 --> 01:09:30,736 1237 01:09:30,736 --> 01:09:33,819 And the reason we're going to create these navigators inside of each other 1238 01:09:33,819 --> 01:09:37,210 is because sometimes, you might not even want to see the stack at all. 1239 01:09:37,210 --> 01:09:39,520 Here we've got a Stack Navigator, but how about let's 1240 01:09:39,520 --> 01:09:42,520 create an example where you want to log in to the app 1241 01:09:42,520 --> 01:09:44,754 before you even see the main stack. 1242 01:09:44,754 --> 01:09:47,170 So in that case, you're going to be switched away from it, 1243 01:09:47,170 --> 01:09:49,899 and you're only going to see a login screen up 1244 01:09:49,899 --> 01:09:52,569 until you're ready to see the actual stack. 1245 01:09:52,569 --> 01:09:56,380 So that's why we're using a switch on the outside of our Stack Navigator. 1246 01:09:56,380 --> 01:10:01,239 Let's go ahead and register the first route, which would be the Main route. 1247 01:10:01,239 --> 01:10:02,030 That's just a name. 1248 01:10:02,030 --> 01:10:03,946 We can call it whatever we want, but I'm going 1249 01:10:03,946 --> 01:10:08,730 to call it Main, because it's our Main Navigator once you're logged in. 1250 01:10:08,730 --> 01:10:10,690 And I'm also going to create Login, which 1251 01:10:10,690 --> 01:10:13,106 is going to be a login screen that we haven't created yet. 1252 01:10:13,106 --> 01:10:15,980 1253 01:10:15,980 --> 01:10:18,710 I'm going to set the initial route name to be the Login 1254 01:10:18,710 --> 01:10:23,600 screen, because we're going to want you to be logged out at the beginning. 1255 01:10:23,600 --> 01:10:24,470 OK. 1256 01:10:24,470 --> 01:10:28,432 So I'm going to get the Switch Navigator from React Navigation. 1257 01:10:28,432 --> 01:10:30,140 And I'm going to get the Screen Navigator 1258 01:10:30,140 --> 01:10:33,250 from not yet implemented area. 1259 01:10:33,250 --> 01:10:36,951 1260 01:10:36,951 --> 01:10:37,450 OK. 1261 01:10:37,450 --> 01:10:39,116 So let's go ahead and create our screen. 1262 01:10:39,116 --> 01:10:44,510 1263 01:10:44,510 --> 01:10:47,860 And I'm going to copy and paste a super simple Login screen. 1264 01:10:47,860 --> 01:10:53,516 1265 01:10:53,516 --> 01:10:55,890 And our Login screen is going to have a couple of styles. 1266 01:10:55,890 --> 01:11:01,023 1267 01:11:01,023 --> 01:11:01,523 OK. 1268 01:11:01,523 --> 01:11:04,241 1269 01:11:04,241 --> 01:11:05,990 So let's see, what does our app look like. 1270 01:11:05,990 --> 01:11:09,200 I think I might not have saved the App file. 1271 01:11:09,200 --> 01:11:09,950 OK. 1272 01:11:09,950 --> 01:11:12,980 So this is the Login screen. 1273 01:11:12,980 --> 01:11:15,500 This warning here is because we're currently debugging, 1274 01:11:15,500 --> 01:11:17,850 and we're kind of done with that right now. 1275 01:11:17,850 --> 01:11:18,350 OK. 1276 01:11:18,350 --> 01:11:20,300 So now we've got our Login screen. 1277 01:11:20,300 --> 01:11:22,460 We have that, because the App Navigator that we're 1278 01:11:22,460 --> 01:11:27,680 rendering down here inside of the app, it is just a Switch Navigator. 1279 01:11:27,680 --> 01:11:29,120 And the initial route is Login. 1280 01:11:29,120 --> 01:11:30,720 So all we see is the Login screen. 1281 01:11:30,720 --> 01:11:33,380 When we press to log in, well, we haven't actually 1282 01:11:33,380 --> 01:11:35,490 implemented the Login functionality. 1283 01:11:35,490 --> 01:11:39,170 So let's pretend that we have a bunch of Login logic right here. 1284 01:11:39,170 --> 01:11:41,396 And instead of actually doing that, we're 1285 01:11:41,396 --> 01:11:43,520 just going to jump straight to the navigation part. 1286 01:11:43,520 --> 01:11:45,650 So let's see this.props.navigation. 1287 01:11:45,650 --> 01:11:51,690 1288 01:11:51,690 --> 01:11:57,820 And we're going to navigate to the Main screen when you tap Log in. 1289 01:11:57,820 --> 01:11:58,320 OK. 1290 01:11:58,320 --> 01:12:02,160 And it switches us over to our stack that we've already implemented. 1291 01:12:02,160 --> 01:12:05,220 Now, what's great about the Navigate function, 1292 01:12:05,220 --> 01:12:07,410 and what's great about composing navigators, 1293 01:12:07,410 --> 01:12:11,070 is that you can actually refer to several different route names here. 1294 01:12:11,070 --> 01:12:15,630 So here, of course, we're referring to the route name for the other navigator. 1295 01:12:15,630 --> 01:12:19,800 So it's just telling us to switch to this navigator, whatever state that 1296 01:12:19,800 --> 01:12:20,907 navigator currently is. 1297 01:12:20,907 --> 01:12:23,490 The initial route named for that navigator is the ContactList, 1298 01:12:23,490 --> 01:12:25,050 so that's why we see that. 1299 01:12:25,050 --> 01:12:29,550 But we could also explicitly navigate to the Contact List. 1300 01:12:29,550 --> 01:12:31,070 Let's try that. 1301 01:12:31,070 --> 01:12:34,810 Press to Log in, you jump to the Contact List. 1302 01:12:34,810 --> 01:12:35,310 OK. 1303 01:12:35,310 --> 01:12:37,980 What if you want to explicitly navigate to something else? 1304 01:12:37,980 --> 01:12:40,920 Like let's explicitly navigate to Add Contact. 1305 01:12:40,920 --> 01:12:41,830 Just as an example. 1306 01:12:41,830 --> 01:12:43,680 It wouldn't really make sense in our app. 1307 01:12:43,680 --> 01:12:49,440 But maybe Add Contact is the first thing that you want somebody 1308 01:12:49,440 --> 01:12:51,490 to do once they log in. 1309 01:12:51,490 --> 01:12:51,990 OK? 1310 01:12:51,990 --> 01:12:54,750 And it jumps you deep inside the stack, but it still 1311 01:12:54,750 --> 01:12:56,600 is normal stack navigation. 1312 01:12:56,600 --> 01:13:00,360 You still go back inside of the stack. 1313 01:13:00,360 --> 01:13:05,973 So here, that's a very simple example of navigator composition. 1314 01:13:05,973 --> 01:13:09,600 1315 01:13:09,600 --> 01:13:13,620 So now, we've seen Switch Navigator, which allows 1316 01:13:13,620 --> 01:13:15,502 us to switch between several screens. 1317 01:13:15,502 --> 01:13:17,460 But Tab Navigator is a little bit more special, 1318 01:13:17,460 --> 01:13:22,530 because it actually has a tab bar that's useful for switching 1319 01:13:22,530 --> 01:13:24,180 between the different screens. 1320 01:13:24,180 --> 01:13:29,670 And also, it'll keep the previous screens that had been available, 1321 01:13:29,670 --> 01:13:31,290 it'll keep their state around. 1322 01:13:31,290 --> 01:13:35,070 So it doesn't actually unmount the components that go away. 1323 01:13:35,070 --> 01:13:38,460 And that's handy, because when you want to switch back to the screen 1324 01:13:38,460 --> 01:13:40,890 it's really fast, and the state is still there. 1325 01:13:40,890 --> 01:13:43,200 If you had scrolled down inside of a certain tab, 1326 01:13:43,200 --> 01:13:46,980 and you switched tabs and switched back, it's still going to be there. 1327 01:13:46,980 --> 01:13:52,030 Now, there are several Tab Navigators that now ship with React Navigation, 1328 01:13:52,030 --> 01:13:55,080 including two of these Material Themes Navigators, 1329 01:13:55,080 --> 01:13:59,820 and a simple Tab Navigator, which is Create Bottom Tab Navigator. 1330 01:13:59,820 --> 01:14:02,940 And as per the other navigators, the Navigate function 1331 01:14:02,940 --> 01:14:04,810 and the goBack function still work. 1332 01:14:04,810 --> 01:14:07,380 So Navigate is how you switch to different tabs, 1333 01:14:07,380 --> 01:14:11,220 and goBack actually does have behavior on Tab Navigator. 1334 01:14:11,220 --> 01:14:13,477 It takes you back to the first tab. 1335 01:14:13,477 --> 01:14:15,810 And this is relevant usually on the Android Back button, 1336 01:14:15,810 --> 01:14:19,300 because you want to be able to jump somebody back to the first tab. 1337 01:14:19,300 --> 01:14:21,330 But you don't want this in every case exactly. 1338 01:14:21,330 --> 01:14:26,010 So the Tab Navigator's goBack behavior can be configured. 1339 01:14:26,010 --> 01:14:29,990 It doesn't necessarily have to take you back to the first tab. 1340 01:14:29,990 --> 01:14:34,670 So with Tab Navigators you can switch between two tabs, but keep in mind 1341 01:14:34,670 --> 01:14:36,570 that the previous tab is still there. 1342 01:14:36,570 --> 01:14:39,181 It's just not visible. 1343 01:14:39,181 --> 01:14:39,680 All right. 1344 01:14:39,680 --> 01:14:42,860 And the way that you create a Tab Navigator is much like the way 1345 01:14:42,860 --> 01:14:44,390 that you create any other navigator. 1346 01:14:44,390 --> 01:14:47,630 You're going to register a couple of routes by their route name, 1347 01:14:47,630 --> 01:14:51,170 and you're going to provide a screen component. 1348 01:14:51,170 --> 01:14:52,129 OK. 1349 01:14:52,129 --> 01:14:54,170 Maybe we should just go jump into our application 1350 01:14:54,170 --> 01:14:57,320 now and implement some of these tabs. 1351 01:14:57,320 --> 01:15:02,270 1352 01:15:02,270 --> 01:15:02,884 OK. 1353 01:15:02,884 --> 01:15:04,300 So this is where we are right now. 1354 01:15:04,300 --> 01:15:08,020 Can press to log in. 1355 01:15:08,020 --> 01:15:09,820 OK. 1356 01:15:09,820 --> 01:15:12,760 The other thing that I'm going to do that I missed before, actually 1357 01:15:12,760 --> 01:15:16,994 with Stack Navigation, we're going to go ahead and theme it. 1358 01:15:16,994 --> 01:15:19,160 We're just going to give it a little bit of a color. 1359 01:15:19,160 --> 01:15:22,682 We've got these navigation options that, in this case, 1360 01:15:22,682 --> 01:15:23,890 we're configuring the header. 1361 01:15:23,890 --> 01:15:27,610 So this is available inside of a Stack Navigator. 1362 01:15:27,610 --> 01:15:31,700 So I'm going to go here to our stack. 1363 01:15:31,700 --> 01:15:34,300 In addition to specifying the initial route name, 1364 01:15:34,300 --> 01:15:37,240 I'm going to specify some navigation options that 1365 01:15:37,240 --> 01:15:40,030 are going to identify the tint color. 1366 01:15:40,030 --> 01:15:42,110 Ooh. 1367 01:15:42,110 --> 01:15:42,670 OK. 1368 01:15:42,670 --> 01:15:45,910 This button we had rendered by hand, which 1369 01:15:45,910 --> 01:15:48,410 is why it's not actually lining up. 1370 01:15:48,410 --> 01:15:50,380 So let's go ahead and fix that really quickly. 1371 01:15:50,380 --> 01:15:53,020 1372 01:15:53,020 --> 01:15:55,420 That would be on the Contact List screen. 1373 01:15:55,420 --> 01:15:58,330 1374 01:15:58,330 --> 01:16:00,755 We can just provide a color right here. 1375 01:16:00,755 --> 01:16:07,080 1376 01:16:07,080 --> 01:16:07,700 OK. 1377 01:16:07,700 --> 01:16:10,910 The other thing is, of course, our Login screen was deep linking here. 1378 01:16:10,910 --> 01:16:12,967 Let's just make it go to the Main Navigator. 1379 01:16:12,967 --> 01:16:16,240 1380 01:16:16,240 --> 01:16:17,110 OK. 1381 01:16:17,110 --> 01:16:20,514 So now let's actually go and jump into adding our Tab Navigator. 1382 01:16:20,514 --> 01:16:23,240 1383 01:16:23,240 --> 01:16:26,450 So I'm going to go into our app. 1384 01:16:26,450 --> 01:16:29,180 And instead of the Main Navigator, let's just 1385 01:16:29,180 --> 01:16:31,432 go ahead and call this the Contacts Tab. 1386 01:16:31,432 --> 01:16:34,640 Because we're going to want to make it so that this whole stack of navigation 1387 01:16:34,640 --> 01:16:37,040 happens inside of a particular tab. 1388 01:16:37,040 --> 01:16:41,180 And you'll notice that it's a pretty common pattern, especially on iOS apps. 1389 01:16:41,180 --> 01:16:42,980 So let's call this the Contacts Tab. 1390 01:16:42,980 --> 01:16:46,100 1391 01:16:46,100 --> 01:16:50,910 And we're going to want to create a new navigator for the-- 1392 01:16:50,910 --> 01:16:53,240 what did we call it-- the Main Navigator. 1393 01:16:53,240 --> 01:16:56,540 So that can be our tabs. 1394 01:16:56,540 --> 01:16:58,850 So the Main Navigator is createTabNavigator. 1395 01:16:58,850 --> 01:17:01,970 1396 01:17:01,970 --> 01:17:05,840 And we're going to want to set up a couple of routes here, 1397 01:17:05,840 --> 01:17:09,641 including, of course, the Contacts Tab. 1398 01:17:09,641 --> 01:17:11,610 And let's create a new tab. 1399 01:17:11,610 --> 01:17:15,010 And that's going to be under Contacts. 1400 01:17:15,010 --> 01:17:18,660 Let's create a new tab for a different area of your application 1401 01:17:18,660 --> 01:17:21,370 that really has nothing to do with the contacts. 1402 01:17:21,370 --> 01:17:24,050 I think a pretty simple example that's somewhat common 1403 01:17:24,050 --> 01:17:26,465 is like a Settings Tab, where you can go and change 1404 01:17:26,465 --> 01:17:28,090 some other configuration about the app. 1405 01:17:28,090 --> 01:17:31,860 1406 01:17:31,860 --> 01:17:34,230 Settings screen. 1407 01:17:34,230 --> 01:17:37,440 So Settings screen, we're going to go import from here. 1408 01:17:37,440 --> 01:17:40,134 Which we haven't quite created it yet, but we're going 1409 01:17:40,134 --> 01:17:41,550 to go ahead and do that right now. 1410 01:17:41,550 --> 01:17:52,850 1411 01:17:52,850 --> 01:17:58,730 And the Settings screen, I'm going to do a little bit of copy/paste once again. 1412 01:17:58,730 --> 01:18:02,820 1413 01:18:02,820 --> 01:18:06,650 And all we're going to be doing is just saying, This is a Settings screen. 1414 01:18:06,650 --> 01:18:09,310 It doesn't even need a navigation link or anything right now, 1415 01:18:09,310 --> 01:18:11,800 because the tabs will be visible. 1416 01:18:11,800 --> 01:18:14,210 So I haven't saved the app. 1417 01:18:14,210 --> 01:18:14,710 Oh. 1418 01:18:14,710 --> 01:18:19,044 I need to import createTabNavigator from React Navigation. 1419 01:18:19,044 --> 01:18:24,360 1420 01:18:24,360 --> 01:18:24,860 OK. 1421 01:18:24,860 --> 01:18:26,750 We're going to press to log in, switching 1422 01:18:26,750 --> 01:18:29,720 to our Main Navigator, which is tabs. 1423 01:18:29,720 --> 01:18:30,630 OK. 1424 01:18:30,630 --> 01:18:37,400 It seems that in the copied/pasted content that I had, I had a slight bug. 1425 01:18:37,400 --> 01:18:39,530 I'm going to go ahead and just fix that by changing 1426 01:18:39,530 --> 01:18:41,867 the scroll view to a normal view. 1427 01:18:41,867 --> 01:18:43,200 It's going to be little simpler. 1428 01:18:43,200 --> 01:18:48,130 But now you can see that we have tabs at the bottom of the screen. 1429 01:18:48,130 --> 01:18:51,200 And the first tab that's selected is the Contacts Tab. 1430 01:18:51,200 --> 01:18:54,830 The second tab doesn't even have a header or anything inside of it. 1431 01:18:54,830 --> 01:18:57,920 And that's because we've switched entirely away from the other navigator, 1432 01:18:57,920 --> 01:19:01,850 and the header was provided by the Stack Navigator. 1433 01:19:01,850 --> 01:19:04,970 So these tabs are looking kind of ugly. 1434 01:19:04,970 --> 01:19:06,800 Let's go ahead and theme them a little bit. 1435 01:19:06,800 --> 01:19:09,360 1436 01:19:09,360 --> 01:19:11,810 So one trick that we have for theming tabs 1437 01:19:11,810 --> 01:19:13,930 is by setting these tab bar options. 1438 01:19:13,930 --> 01:19:16,970 We can set the active tint color, which is the color of the active tab. 1439 01:19:16,970 --> 01:19:20,190 1440 01:19:20,190 --> 01:19:21,390 So let's jump into there. 1441 01:19:21,390 --> 01:19:24,740 1442 01:19:24,740 --> 01:19:26,825 Here where we're creating our Tab Navigator, 1443 01:19:26,825 --> 01:19:36,620 we can set Tab Bar Options and Active Tab Color. 1444 01:19:36,620 --> 01:19:38,870 I'm going to copy that from right here so that we 1445 01:19:38,870 --> 01:19:41,190 have a nice cohesive theme for our app. 1446 01:19:41,190 --> 01:19:43,730 1447 01:19:43,730 --> 01:19:45,910 Press to log in. 1448 01:19:45,910 --> 01:19:46,410 Oops. 1449 01:19:46,410 --> 01:19:50,160 1450 01:19:50,160 --> 01:19:53,310 My guess is I had a nice typo here. 1451 01:19:53,310 --> 01:19:56,981 So let me go ahead and find my-- 1452 01:19:56,981 --> 01:19:57,480 I see. 1453 01:19:57,480 --> 01:20:03,720 I said-- it's Active Tint Color and not Active Tab Color. 1454 01:20:03,720 --> 01:20:04,950 OK. 1455 01:20:04,950 --> 01:20:06,660 So now our tint color matches. 1456 01:20:06,660 --> 01:20:11,010 Now generally, when we have tabs at the bottom on an iOS app, 1457 01:20:11,010 --> 01:20:15,990 you really want to have icons, because this just looks bizarre if you don't. 1458 01:20:15,990 --> 01:20:23,640 So let's introduce a new concept of adding vector icons to our application. 1459 01:20:23,640 --> 01:20:28,590 Now this is how you can specify the Tab Bar Icon. 1460 01:20:28,590 --> 01:20:31,720 But first we're going to need to install a new library. 1461 01:20:31,720 --> 01:20:36,480 So we're going to go to do npm install dash save, react-native-vector-icons. 1462 01:20:36,480 --> 01:20:40,450 In my case, I'm going to use Yarn. 1463 01:20:40,450 --> 01:20:44,670 I'm going to go right here and say, yarn add react-native-vector-icons. 1464 01:20:44,670 --> 01:20:49,110 1465 01:20:49,110 --> 01:20:49,610 All right. 1466 01:20:49,610 --> 01:20:52,010 While that's installing, I'm going to go start using it. 1467 01:20:52,010 --> 01:20:54,590 As you can see, you can import it like this, 1468 01:20:54,590 --> 01:20:57,433 and render it with a couple of conventions like that. 1469 01:20:57,433 --> 01:21:02,990 1470 01:21:02,990 --> 01:21:06,320 So I'm going to grab my snippet here. 1471 01:21:06,320 --> 01:21:09,080 So here you can see that we're manually applying 1472 01:21:09,080 --> 01:21:13,610 navigation options onto the main stack. 1473 01:21:13,610 --> 01:21:15,800 Or rather, instead of the main stack, in this case 1474 01:21:15,800 --> 01:21:18,110 we've called it the Contacts Tab. 1475 01:21:18,110 --> 01:21:22,130 So we're going to set the options for the Contacts Tab. 1476 01:21:22,130 --> 01:21:26,780 And here we are using a pretty fun trick where we've got a string template. 1477 01:21:26,780 --> 01:21:29,630 And the Tab Bar Icon is a pretty special navigation 1478 01:21:29,630 --> 01:21:32,900 option that is defined as a function. 1479 01:21:32,900 --> 01:21:35,780 And it's told both what the tint color is, 1480 01:21:35,780 --> 01:21:38,450 and whether or not the tab is currently focused. 1481 01:21:38,450 --> 01:21:41,330 And the reason we need to know whether or not the tab is focused 1482 01:21:41,330 --> 01:21:44,510 is because, generally, we're going to render a different style of icon. 1483 01:21:44,510 --> 01:21:51,680 1484 01:21:51,680 --> 01:21:55,950 So if it's focused, we're going to just render iOS Contacts. 1485 01:21:55,950 --> 01:22:00,150 And if it's not focused, then we're going to render iOS Contacts Outline. 1486 01:22:00,150 --> 01:22:03,350 So that's what this trick is doing inside of this-- 1487 01:22:03,350 --> 01:22:07,475 you know, we've got a ternary inside of our string template. 1488 01:22:07,475 --> 01:22:08,600 So let's see if that works. 1489 01:22:08,600 --> 01:22:15,048 I need to import Ionicons from react-native-vector-icons. 1490 01:22:15,048 --> 01:22:22,000 1491 01:22:22,000 --> 01:22:22,500 OK. 1492 01:22:22,500 --> 01:22:25,410 1493 01:22:25,410 --> 01:22:28,500 I'm going to press to log in, and our icon is showing up here. 1494 01:22:28,500 --> 01:22:32,130 You can see that when we blur it, it switches to a different icon. 1495 01:22:32,130 --> 01:22:36,510 So that's why we have that kind of crazy template string 1496 01:22:36,510 --> 01:22:39,809 that we're using to select the current icon. 1497 01:22:39,809 --> 01:22:42,600 So let's go ahead and do something similar for the Settings screen. 1498 01:22:42,600 --> 01:22:45,330 1499 01:22:45,330 --> 01:22:48,900 But here we're going to actually put it on the screen static navigation 1500 01:22:48,900 --> 01:22:50,020 options. 1501 01:22:50,020 --> 01:22:53,860 So here, the static navigation options are empty. 1502 01:22:53,860 --> 01:22:57,930 I'm going to want to provide a Tab Bar Icon. 1503 01:22:57,930 --> 01:23:01,100 And here we're going to provide just the same one for now, 1504 01:23:01,100 --> 01:23:02,856 just to make sure that it works. 1505 01:23:02,856 --> 01:23:06,840 1506 01:23:06,840 --> 01:23:07,950 OK. 1507 01:23:07,950 --> 01:23:09,107 That looks a little weird. 1508 01:23:09,107 --> 01:23:10,773 So I think it's going to be iOS options. 1509 01:23:10,773 --> 01:23:14,557 1510 01:23:14,557 --> 01:23:17,129 Ooh, options. 1511 01:23:17,129 --> 01:23:17,670 Looking nice. 1512 01:23:17,670 --> 01:23:20,670 1513 01:23:20,670 --> 01:23:23,010 Great. 1514 01:23:23,010 --> 01:23:27,270 So here, just to do a quick recap of all the navigation features 1515 01:23:27,270 --> 01:23:30,810 that we've added to the app in a relatively short period of time, 1516 01:23:30,810 --> 01:23:32,535 I'm just going to open up the App file. 1517 01:23:32,535 --> 01:23:34,410 And we're going to start at the bottom, where 1518 01:23:34,410 --> 01:23:37,460 we're rendering our App Navigator. 1519 01:23:37,460 --> 01:23:39,810 Now our App Navigator can be given access 1520 01:23:39,810 --> 01:23:43,010 to screen props, which are various properties that are going 1521 01:23:43,010 --> 01:23:45,900 to be available on every single screen. 1522 01:23:45,900 --> 01:23:48,332 Of course, in larger applications, you might not 1523 01:23:48,332 --> 01:23:50,040 want to use screen props, because it will 1524 01:23:50,040 --> 01:23:54,990 it'll cause every screen to re-render when any of these screen props changes. 1525 01:23:54,990 --> 01:23:58,470 So you might want to use a different technique to deal with that. 1526 01:23:58,470 --> 01:24:01,050 But here you can see we're just rendering our App Navigator. 1527 01:24:01,050 --> 01:24:03,390 Our App Navigator is a higher order function, 1528 01:24:03,390 --> 01:24:05,630 is the result of a higher order function call. 1529 01:24:05,630 --> 01:24:08,070 It's a higher order component. 1530 01:24:08,070 --> 01:24:10,260 It's that we're creating a Switch Navigator. 1531 01:24:10,260 --> 01:24:14,970 And that's why, at the very beginning, it covers up the whole screen, 1532 01:24:14,970 --> 01:24:17,040 because it's our top-level navigator that's 1533 01:24:17,040 --> 01:24:21,480 switching away from the Tab Navigator. 1534 01:24:21,480 --> 01:24:22,980 And that's what we have in here. 1535 01:24:22,980 --> 01:24:26,850 Inside of our Main Navigator, this is a Tab Navigator, 1536 01:24:26,850 --> 01:24:27,990 where we've got two tabs. 1537 01:24:27,990 --> 01:24:30,340 You've got the Contacts Tab and the Settings Tab. 1538 01:24:30,340 --> 01:24:34,410 So first, we need to navigate on the outer navigator, which is the switch, 1539 01:24:34,410 --> 01:24:37,080 and now we can access the inner navigators. 1540 01:24:37,080 --> 01:24:39,775 In this case, the next inner navigator is allowing us 1541 01:24:39,775 --> 01:24:41,400 to switch between these different tabs. 1542 01:24:41,400 --> 01:24:44,250 1543 01:24:44,250 --> 01:24:48,030 Of course, inside of the main tab, inside of the Contacts Tab 1544 01:24:48,030 --> 01:24:49,710 we have a whole stack. 1545 01:24:49,710 --> 01:24:53,580 So that's what we're setting up up here with createStackNavigator. 1546 01:24:53,580 --> 01:24:56,580 We're registering three screens inside of our stack. 1547 01:24:56,580 --> 01:24:59,964 And inside of each of our screens we're setting various navigation options. 1548 01:24:59,964 --> 01:25:03,130 And the default navigation options are the ones that are provided down here. 1549 01:25:03,130 --> 01:25:05,820 1550 01:25:05,820 --> 01:25:09,090 The navigation options are what's setting up the button in the header 1551 01:25:09,090 --> 01:25:12,934 and the title, as well as the color. 1552 01:25:12,934 --> 01:25:14,850 And each of these screens are able to navigate 1553 01:25:14,850 --> 01:25:18,840 between each other using the Navigate functionality in this dot props dot 1554 01:25:18,840 --> 01:25:20,520 navigation. 1555 01:25:20,520 --> 01:25:23,730 So I think that's a quick introduction to what it's 1556 01:25:23,730 --> 01:25:28,020 like to use React Navigation inside of a fresh React Native app. 1557 01:25:28,020 --> 01:25:29,860 And I hope you enjoyed it. 1558 01:25:29,860 --> 01:25:32,937 And if you've got any questions, feel free to take 1559 01:25:32,937 --> 01:25:34,770 a look at some of these additional resources 1560 01:25:34,770 --> 01:25:38,160 that we have available for you, and get in touch with me 1561 01:25:38,160 --> 01:25:40,650 and Brent on Twitter and GitHub. 1562 01:25:40,650 --> 01:25:42,200 Thanks. 1563 01:25:42,200 --> 01:25:44,124