
No Comments Yet
Be the first to share your thoughts and start the conversation.
Be the first to share your thoughts and start the conversation.
How did you manage to remove the blur property and reach here?
Upgrading gives you access to quizzes so you can test your knowledge, track progress, and improve your skills.
By logging in, you'll unlock full access to this and other free tutorials on JSM Pro.
Why? Logging in lets us personalize your learning experience, track your progress, and keep you in the loop with new workshops, coding tips, and platform updates.
You'll also be the first to know about upcoming launches, events, and exclusive discounts.
No spam—just helpful content to level up your skills.
If that sounds fair, go ahead and log in to continue →
Enter your name and email to get instant access
In this lesson, we explore how to implement routing in React Native applications, drawing parallels to Next.js routing practices. We start with the basic setup, emphasizing the importance of defining routes as files within the app folder, and gradually build out a navigation structure featuring a home screen, onboarding process, and dynamic movie details.
onboarding.tsx
, using a simple boilerplate command (rnfes
).expo-router
and href attributes.00:00:02 It's time to do the routing.
00:00:04 And as I mentioned before, routing in React Native works similarly to routing in Next.js.
00:00:10 But even if you haven't tried it in Next.js, don't worry because I'll show you exactly what that means.
00:00:15 It simply means that your file within the app folder represents your route and the file name is a URL pointing to that route.
00:00:24 For example, the app.index.tsx represents your home route, the starting point of your app.
00:00:31 And if you want to create another route, like let's say you want to onboard users to your app, you can create a new file and let's call it onboarding.tsx.
00:00:40 And within it, you can run rnfes, which is a simple React Native functional export with component styles.
00:00:49 So just a quick boilerplate so we don't have to write it by hand.
00:00:52 If this didn't work for you, that must mean that you don't have the React and React Native extension for plugins installed,
00:00:59 so just search for your plugins and search for React or React Native plugins.
00:01:03 Once you've created this route, we have to figure out how we can get to it from the index route.
00:01:09 So let's head over into the index and just below the view that says welcome, let's put a link coming from expo router and let's give it an href of forward
00:01:19 slash onboarding and it can simply say onboarding.
00:01:22 If we save it, you can see it right here on your screen.
00:01:25 And if you try clicking on it, you can see that it says unmatched route, but let's first reload.
00:01:30 I'll open up my terminal and press the letter R and click on onboarding.
00:01:35 And there we go, we have been redirected to the onboarding screen.
00:01:38 And now you can use all your device's native back and forward functionalities, such as on iPhone, it is normal to scroll from left to right to go back.
00:01:47 This works seamlessly.
00:01:49 Similarly, let's say you want to create a route that shows the details of a movie.
00:01:54 Well, we can create a new folder, and let's call it Movie.
00:01:59 And within Movie, we can create a dynamic route.
00:02:02 So that means creating a file in which we wrap its name within square brackets.
00:02:08 And you can define what the actual parameter is.
00:02:11 In this case, I'll wrap it in a square brackets of id.tsx.
00:02:17 Here, you can once again run rnfes, and this will create a boilerplate function, which we have to fix a bit.
00:02:25 I'll call it details, export default details, and we have a style sheet at the bottom.
00:02:32 So now the question is, how can we know on which movie's details page we're on?
00:02:36 Are we on the Iron Man's details page or Batman's, for example?
00:02:40 Well, we can extract the route param information in Expo like this.
00:02:45 By saying const, the structure, whatever name or title you put within the square brackets, and then get it from use local search programs coming from the
00:02:56 export router.
00:02:57 If you do this now, you can use this ID variable.
00:03:00 So I'll say movie details.
00:03:03 And then I'll render the dynamic ID right here.
00:03:06 So now back in our index.tsx, we can create another link.
00:03:12 And this one will point to forward slash movie, forward slash Avengers.
00:03:19 And we can say Avenger movie.
00:03:23 If we go back, you can now see this new link and don't forget to reload.
00:03:28 So one more time, just press the letter R and wait until it reloads.
00:03:32 So we make sure that this new route we created is recognized.
00:03:35 You'll have to do this whenever you add some new pages.
00:03:38 Now, if you click on the second link, you'll see that we go to the movie details page, but it knows that we are on the Avengers movie details.
00:03:47 You can play with that a bit more to fully understand how routing works, but what I'll do for now is remove those two examples that we have created by
00:03:57 entirely removing the movie folder as well as the onboarding file.
00:04:01 That's because I want to teach you how you would begin creating the screens for your entire application by first looking at the design.
00:04:10 This right here is a typical React Native application.
00:04:13 Well, it definitely has a design better than most of the apps out there, but you get the idea.
00:04:18 We have the homepage, some kind of a search page, and also a details page for whatever it is that we're searching through.
00:04:25 We also have a bottom navigation for the home screen, search, saved, and the profile.
00:04:32 And of course, there's also Auth.
00:04:33 So if you'd like me to extend this React Native course to include authentication too, let me know down below.
00:04:39 But with that in mind, we now have to figure out how many screens we have, and for each one of these screens, we have to give it a proper route.
00:04:48 First of all, there's the home screen, the search screen, the save or bookmark screen, the profile screen, and finally, the movie detail screen.
00:04:58 Out of these four screens, we only want to show the tab navigation for the first four screens and not the movie details,
00:05:05 because we'll get to the movie details by, of course, clicking on the movie card.
00:05:09 Expo allows us to do just that with route grouping.
00:05:14 We can prevent a segment from showing in the URL by using the group syntax, which is just a pair of parentheses.
00:05:22 So for example, if we have app-root-home.tsx, it'll match the home And if we don't put it into a route group, then we'll have to say route home,
00:05:32 which we don't want to do.
00:05:33 So groups are great for organizing sections of the app.
00:05:37 So let me show you how we can group our routes within the application.
00:05:41 First, let's create a group route folder for our tabs.
00:05:45 I'll call it, in parentheses, tabs.
00:05:49 Within tabs, we can create a new underscore layout dot tsx.
00:05:53 So now we want to ensure that we show the mobile navigation only on that screen.
00:05:59 Keep in mind that there can only be one index dot tsx route.
00:06:02 And right now it is right here in the root of the directory, but we actually want to put it within tabs because the homepage is a part of the tabs layout.
00:06:11 Next, let's create the other three routes by creating a new file and naming it profile.
00:06:19 Let's quickly run rnfe, which will quickly spin up a new functional component.
00:06:26 And let's create a second file right here, or a second screen, should I say, and let's call it saved.tsx.
00:06:34 Also run rnfe, and finally create the last screen.
00:06:39 Let's call it search.tsx and run rnfe.
00:06:44 Now for the movie details, since it's outside of that tab layout, we want to create it within the app by creating a new movies folder.
00:06:54 And within movies, create a new dynamic route of id.dsx within square brackets.
00:07:02 There you can also run rnfe and make sure to fix the name to movie details.
00:07:09 There we go.
00:07:11 Perfect.
00:07:12 Now we want to hide this ugly header that we have right here at the top that says index.
00:07:17 How can we do that?
00:07:19 Well, we can head over into the app layout.tsx.
00:07:22 That is this one that we had from before, not the one within tabs.
00:07:26 And here we can expand the stack component.
00:07:30 And within it, we can render something known as a stack.screen, which is a self-closing component where we can give it a name and say that it'll be a string
00:07:41 of tabs.
00:07:42 This is the route group which we created.
00:07:45 And we can also give it options of header shown is false.
00:07:50 And we also want to repeat this stack.screen for our movie details page by saying name is equal to movie forward slash ID like this.
00:08:02 And we can say.
00:08:04 Options, header shown is set to false.
00:08:08 If you save this and reload, because the header is still here.
00:08:13 Well, to hide it completely, we have to head over into the underscore layout of the tabs folder, and then you can run rnfe right here to create a new layout.
00:08:24 Instead of returning a view right here, let's instead return something known as tabs, coming from ExpoRouter.
00:08:32 Within tabs, you can render a tabs.screen component.
00:08:36 It is a self-closing component that has a name, in this case it's index for the homepage, and then you can provide additional options.
00:08:46 Here, you can also provide a header shown is set to false, as well as a title set to something like home, as this is the homepage.
00:08:55 Now, if you reload your application by opening up your terminal and pressing the letter R, you'll see that there is no header shown on top.
00:09:03 And if I comment out this tabs.screen, you can see that we still have index, so it is hiding that single route.
00:09:11 And then this one, stack that screen, if you comment it out, this one is actually hiding the group route.
00:09:18 So we are right now under tabs, index.
00:09:21 This one right here hides the route groups header.
00:09:25 And this one right here hides that specific screens header.
00:09:29 And it also gives it a name, which is then shown right here at the bottom.
00:09:33 So tabs allow you to modify how your bottom navigation looks like.
00:09:37 Now, why did I say modify and not create your tabs navigation?
00:09:42 Well, that's because you can see even though we have only declared the home route immediately right off the bat, three additional routes are here and they
00:09:51 work out of the box.
00:09:52 We didn't do anything, but yet React Native recognized that we have three other routes right here, profile, saved, search,
00:10:00 and then the home, and at the bottom, we can switch between them.
00:10:04 But what tabs allow to do is to further customize them.
00:10:07 So let me say tabs.screen.
00:10:11 Make it self-closing and let's give it a name of search as well as the options of title search and header shown set to false.
00:10:20 So now we can see it has a capital S right here and let's duplicate it two more times.
00:10:26 This one for the saved.
00:10:28 So let me call it name saved and title of saved.
00:10:32 Make sure that you called it exactly as you did right here.
00:10:35 And the last one will be profile and I'll call it profile.
00:10:41 So now no matter in which route we are, you can see that the header is hidden.
00:10:45 But this results in a super basic, boring navigation.
00:10:49 To make it look more similar to what we have on the design, we have to customize it by defining different icons for each tab of the navigation screen.
00:10:57 So I took the time to find some cool images and icons so I can share them with you.
00:11:02 Below this lesson, you'll find this project's video kit, which includes the link to the project repo, which then includes the README that has the assets.
00:11:11 So simply go here and download them.
00:11:13 Once you download them, simply unzip them, head over within your project and delete the current assets folder as we don't need it.
00:11:21 Then simply drag and drop all of these folders within your movie app.
00:11:26 There we go.
00:11:28 I'll now explain everything that we brought in here.
00:11:30 First, we have the assets.
00:11:33 The assets contain the font that we'll be using, some icons such as the home, logo, person, and more, and also some images like the background image,
00:11:42 the highlight, logo, and more.
00:11:45 We also have some constants such as the icons and images where we export all of these images from a single file with a specific name so it's easier to
00:11:55 import them later on.
00:11:56 And we also have some interfaces so that TypeScript knows what kind of fields will each one of our documents have.
00:12:02 So with that in mind, let's head back over to our tabs layout to make our tabs go from this right here at the bottom to something that looks more like this.
00:12:14 We can start customizing them.
00:12:16 Let's start with the Home tab button.
00:12:18 React Native, specifically the tab screen, allows us to specify how the tab bar icon will look like.
00:12:26 You can provide a callback function where you get access to the state of that specific icon, whether it has currently been clicked or not.
00:12:35 And then here, we can return an empty React fragment for now.
00:12:40 And within it, we can return maybe like a background image.
00:12:44 What do you think?
00:12:45 So first, I'll return an image background coming from React Native that'll have a source equal to...
00:12:55 images, make sure to click enter right here before you finish typing them to auto-import them from constants.
00:13:02 My WebStorm did that very nicely for me here.
00:13:05 So you can see that I imported images from add forward slash constants forward slash images.
00:13:10 And then we can say images dot highlight.
00:13:13 Highlight is this little part.
00:13:15 So when we're currently on that screen, you can show this little pill-like shape.
00:13:19 Next, within this image background, we can render a regular image coming from React Native with a source equal to images.home.
00:13:30 And we can give it a tint color equal to hash 151312 as well as a class name equal to size-5.
00:13:44 And we can close it right here.
00:13:46 And we can also give it a text property that'll simply render the word home.
00:13:51 Okay, so now this is looking a bit off, definitely not what we expected.
00:13:56 So let's style it a bit.
00:13:58 I'll give this source a class name equal to flex flex-row w-full flex-1 min-w of 112 pixels I found this value to work the best with a min height of 14
00:14:19 a margin top of 4 justify-center items-center to fully center it, rounded-full and overflow-hidden.
00:14:31 There we go.
00:14:31 So now we have this real pill-like shape if it's active.
00:14:35 Let's also render an actual icon.
00:14:37 It is under icons.home, but also make sure to import the icons from constants.
00:14:43 And now we can see this icon and we can style this text by giving it a class name of text-secondary, text-base.
00:14:53 font-semi-bold and margin-left of 2. Okay, so this is looking good.
00:15:01 Now, we want to repeat this for every single icon.
00:15:04 And instead of copying this code and duplicating it four times, let's actually extract it into its own custom component.
00:15:12 So this is not a React Native specific thing.
00:15:15 It is just how we do things around React.
00:15:17 So take this as a mini lesson.
00:15:19 Whenever you have to repeat this multiple times, it's better to extract it.
00:15:24 Okay?
00:15:25 So now I'll take this entire image background and I'll create a new component out of it by saying const.
00:15:33 TabIcon is equal to a functional component that returns this image background, which I can just paste right here.
00:15:42 But it seems like we have an error.
00:15:43 So let's put this component to use by rendering it right here, instead of the code that was previously on here.
00:15:50 TabIcon.
00:15:51 And immediately we get the same output, but it looks so much better.
00:15:56 But now, here's the problem.
00:15:57 Whenever you extract something into a custom component, well, how are you going to reuse it, right?
00:16:03 Because now, if I head into the options of the search screen, and I say something like tab bar icon, where, again, we can define how it looks like,
00:16:13 and then I specify that when I show some kind of an icon, well, what happens?
00:16:19 It's going to be the same one as in the home.
00:16:21 So, of course, we want to figure out a way of how we can differentiate those two places where that component is being used.
00:16:29 And here, this is a mini lesson on reusability.
00:16:33 You want to figure out how to make a custom component reusable.
00:16:38 And you can do that, of course, through props.
00:16:41 So many things here are always going to be the same, such as the image background component, the classes we're going to use,
00:16:47 and the colors of the text.
00:16:49 But what will change is going to be the icon, the text, and maybe the state of the focus.
00:16:56 Are we currently on home or are we on search?
00:16:58 So whatever changes from component to component, you have to pass it as a prop.
00:17:03 I'll pass a focus state equal to focused, as well as an icon equal to icons.home, as well as a title equal to home.
00:17:13 And I'll put it into multiple lines so it's easier to read.
00:17:16 I'll copy it and I'll paste it right here for the search.
00:17:20 But for the search, of course, it's not going to be just icons.home.
00:17:25 It's going to be icons.search and the title will be set to search.
00:17:30 And now we can also just copy this entire tab bar icon and add it for the other two icons.
00:17:37 This one, the third one, will actually be called save.
00:17:41 So I'll say tab icon, icons.save and the title can be saved.
00:17:47 The icon name is saved without the D, but I decided to add the D right here, saved.
00:17:53 And finally, the last one will be the profile.
00:17:56 So here we can render focused, icons.person and the title will be profile.
00:18:04 Now, if I save this, you can still see that all four of them say home, but now let me collapse them just so you can see how tidy this looks like.
00:18:14 There we go.
00:18:14 So now we have four different tab screens with different titles and icons.
00:18:19 And the only thing we have to do is extract those props right here at the top.
00:18:25 focused, icon, and title.
00:18:28 For now, we can make them of the type any, and we have to use them whenever something has to be dynamic.
00:18:33 So instead of icons.something, I'll simply render the icon that we're passing through props.
00:18:39 And here, instead of saying home, I will render the title.
00:18:43 If I now save this, you can see that the icons for all four of them have changed.
00:18:48 Also, not always we want to show this image background.
00:18:51 We only want to show it if it's focused.
00:18:54 So I'll say if focused.
00:18:56 In that case, we can return whatever is right here.
00:19:02 So I'll indent it properly and end it.
00:19:05 Else, I'll return something much simpler, like a simple view that'll render an image of a source equal to icon, a tint color equal to hash A8B,
00:19:19 5db and a class name of size of 5. Of course, import the view from React Native and give it a class name of size-full, justify-center,
00:19:31 items-center, margin-top of 4, and the rounded-full.
00:19:37 If you do that, you'll notice that now the icons are going to look much better.
00:19:41 So let's collapse our tab icon.
00:19:44 And let's further customize how all of the icons together look.
00:19:48 We can do that through options, not on the individual tab screens, but we can do it directly on the tabs by saying screen options.
00:19:58 And here we can say tab bar show label.
00:20:02 We can set that to false.
00:20:04 So now we have no labels, just the icons.
00:20:07 We can also modify the tab bar item style, and I'll give it a width of 100%, a height of 100% as well.
00:20:19 I'll give it a justify content of center, as well as align items of center as well.
00:20:26 And we can also modify the tab bar style.
00:20:30 So this is the entire tab on its own, where I'll change the background color to hash 0f0d23.
00:20:39 Border radius will be set to about 50. There we go.
00:20:45 We can also give it a margin horizontal of about 20. Let's also give it a margin bottom of 36. A height of 52. a position of absolute overflow of hidden
00:21:02 and border width of just one With a border color, which is going to be the same color we used above, 0F0D23.
00:21:13 And there you have it.
00:21:14 We have a navigation bar that looks much more similar to the one we have here.
00:21:18 To make it perfect, we just have to fix this small little inconsistency where the height of this pill-like shape is not matching the height of the entire bar.
00:21:27 So let's quickly head over into the tab icon and increase the min age from 14 to 16. And that did the trick.
00:21:36 Perfect.
00:21:37 So now take your phone in your hand and just click between different pages.
00:21:41 You'll only see welcome on the home screen and the rest of the pages will appear blank.
00:21:46 But if you pay close attention to the top left corner, you'll see that some text is changing.
00:21:51 It's just that it's not visible within our current view.
00:21:55 But if you've been paying close attention to the crash course, I already mentioned that there's an element that can help us make sure that everything fits
00:22:02 nicely within the screen.
00:22:03 So we'll explore it soon, but I'm already super happy with this because you have just implemented a fully functional routing system with a custom bottom
00:22:14 navigation bar that allows us to switch between four different screens.
00:22:18 Great job.
00:22:19 I know this was a long lesson, so I'll keep the next one much shorter, but equally as important.
00:22:25 I'll show you how to customize the logo of your application.
00:22:29 So when users want to use it, they know where to click.