Complete React Native Tutorial #4 - Layouts and Stack
Key Takeaways
This video tutorial demonstrates the use of Expo Router, Expo, and React Native to develop native apps, focusing on layouts and stack navigation. It covers creating layout files, using the stack component, and customizing navigation behavior.
Full Transcript
Okay then my friends, now we've got a few different pages and we're linking between them. I think it's time to introduce something called layout files and also a navigation component called stack. So let's start with the layout file which is basically a component and a template which wraps the rest of our pages. So any common content like maybe a small footer that belongs on every page you could place in a layout file and then because that layout wraps the rest of our pages that footer content gets shown on every page automatically. So then how do we register a new layout file? Well pretty simply all we need to do is make a new file in this app folder called underscore and it must start with an underscore layout.jsx. And inside this file, we're going to boilerplate a new component by typing R NFS and then hitting tab. And then we're going to call this component root layout because it's going to be the root layout of the application. Now, inside this layout file, we can add any content that we want to wrap the pages with. For example, we've got this text right here, which I'll just change to say footer. And actually, I'm also going to give this view a new inline style. Um, and that is to set the flex property to be one. so that it's going to stretch to take up the whole height of the page. All right. And now when this layout wraps the pages, this footer text should appear on each page. But at the moment, this layout file isn't actually wrapping anything. And if we reload the app by shaking the device and just saying reload, then we're only going to see that footer text and none of the page content. Right? So by default when we don't have a layout file when we don't have one the expo router automatically renders the index page right but when we do have a root layout file present like this called underscore layout then it automatically renders that layout file instead which is why we see this and now we have to explicitly tell the expo router where we want to output the page content within the layout. So to do that, we could use a component from Expo Router called slot. So let's just add that right above the footer text. And if you start typing it, then you should see an input option to bring in the slot component from Expo router. So if you click on that, it's going to autoimp import it at the top of the file. All right. So now we're saying, look, I want you to render the page content right here in the layout. And now if we save this file, you should see that automatically Expo drops in the index page component to begin with. But underneath that now, we're going to see that footer text from the layout squashed right at the bottom and also hidden a little bit. But as we navigate between all the different pages, you're going to notice that the footer text remains for each one because it's in the layout file which wraps whatever page we're currently viewing. Okay, so that's how we make a layout file and also how we can slot the page content into the layout file using the slot component. But I still think the navigation experience in the app is a little bit clunky and it would be nice to have a little heading bar at the top of each page with maybe a back button. So we can click on that to go to the previous page and then also back again if we wanted to keep cycling through the history. And we can do that using a navigation component called stack instead of slots. And we'll just use that right here. We'll replace the slot component with a stack component instead, which we also need to import from the Expo router package. So the stack component actually does what the slot component was doing before. It renders our pages, but now it also automatically adds navigation behavior like a back button at the top of the page. Now, once you've saved this, you might need to refresh the app again to catch those changes. And what I've noticed is that when you make changes specific to navigation, like adding new pages or maybe adding different routing mechanisms like the stack or something else, a lot of the time you'll need to refresh the app to see that change. But when you're making content changes to existing pages or existing routing mechanisms, more often than not then you don't need to refresh the app. Anyway, now we can see over here on the right the same page, but this time we've got a heading bar at the top that says the page title. And if we navigate to a different page, the title of that new page is going to be at the top as well. Also, we've got this little back arrow in the top left, which we can press to get back to the previous page, which is much better. And this mechanism works for multiple pages in history as well. So, if we go to a different page and then from there we go to another page, we'll be able to cycle back through all the history to both previous pages. Okay. So just a very quick bit of theory here as to how this is all working and why this navigation component is called stack. So when we visit a page in the app, that page gets added to something called a stack, which is just that. It's like a stack of pages. And then if we visit another page, that gets added to the stack on top of the previous one. And if we visit another page, then that page gets added as well. Now, if we hit the back button at this point, the most recently added page gets popped back off the stack and we see the previous page again. If we hit the back button a second time, then the next topmost page gets popped off the stack and we see the initial page again. So, I just thought this would be a nice mental model to have when you're using the stack component for navigation within the app. Okay, so we've got this stat component in the layout right now, which we know is a navigation component, and that drops the page content right here. But it also adds that header at the top of each page and adds the back buttons as well to cycle through the history. Now, in terms of the layout itself, I don't think we need the footer text for the application. So, I'm going to get rid of that. I only wanted to put that there to demo how this works. And actually we don't need the root element to be a view either because the page content itself that gets dropped right here where the stack is well that contains a view in each case is the root element of the page. So we can get rid of the view but we are going to keep the stack. Now at the moment the stack is a self-closing component. It doesn't have an opening and closing tag and that's because nothing needs to go inside it. But if we want more flexibility and customization about how each page in the stack behaves, then we can make this into an opening and a closing tag instead. And then inside this stack, we can register each screen individually and apply some options to those screens. Now to do that, we use configuration components called stack.creen. So we don't need to import anything extra because this is accessed directly from the stack component. But now on this screen component, we can add a name prop to declare the name of the screen, which should match the file name without the extension. So for example, index, which tells the stack we're now registering the screen with a file name of index. And then we can also add an options prop to this as well to set up any options for this particular page or screen. So the value of this should be an object. And there's a bunch of different properties available to us inside this options object. For example, I could use the title property to specify the title, which should be in the heading of this page in that little header bar at the top. Now, by default, the title matches the file name. And therefore, this name value right here, which is index, is what we're going to see over here. But instead, I might want that to say home. So, I'll add that value and then save the file. And then over here we should see that change up at the top. Awesome. Okay. So let's add the next screen component by saying stack.screen again. And this time the name of the screen is about which matches the file name. And then we can also add an options prop to this to change the title again because currently the title on the about page is lowerase which matches the file name. Right? But I want the title to start in uppercase. So I'm going to say about but this time with a capital A. All right. Cool. So that is the second screen registered. Now let's do the last one for the contact page. So again we're going to use stack.screen to register this and we'll give it a name to match the file name which is contact. And again we'll add an options prop to this so that we can set the title property to be contact but with a capital C instead of a lowercase one. Awesome. Also another option that we could add if we wanted to is one called header shown. And the value of this could be either true or false. Now the header is the section at the top of each page where the title is. And by default when we use a stack it does show. But we could set this to be false instead. And then if I was to navigate to that page, we should see that the header wouldn't be there anymore. Okay. All right. So that's how we can register the different screens within a stack and also apply options to each one individually. But we could also add options globally to each screen in the stack by adding a prop to the stack component itself called screen options this time. And the value of this prop should also be an object which contains different properties for the options we want to set globally for all screens. All right. So the options available to use inside this screen options prop are the same ones as those inside the options prop on the individual screens. But when we use them here, they're applied to all the screens inside it. So then let's add a few different options. The first one I'm going to use is one called header style. And this lets us style the appearance of the header. So the value of this is an object in itself. And inside this object, we can use a property called background color to change the color of the header. For now, I'm going to change this to a hex code, which is going to be hash and then ddd, a light gray. Okay. So after the header style, I'm going to add a property called header tint color. And this property refers to the color of the title and the back button in the header itself. I'm going to use a value of hash 333, which is like a dark charcoal gray color. And there's other options we could use here as well, but for now, I think that's all I want to do. So then now this background color and this tint color should be applied to every single screen inside the stack. And if we preview that over here, we should see those subtle changes have taken effect. Awesome. Also, I just want to mention that even if you have global options set up here on the stack component itself, you can override those same options by adding them to individual screens. All right. So then, my friends, we've now implemented a layout file and the stack navigation mechanism to this application. In the next lesson, we're going to apply light and dark theme colors to the project as well.
Original Description
In this complete React Native tutorial, you'll learn how to develop native apps from the ground up, using React Native and Expo. You'll learn about native components, routing, navigation, styling, authentication and a lot more too.
🔥🥷🏼 Get instant access to ALL premium courses on NetNinja.dev:
https://netninja.dev/
🔥🥷🏼 Get instant access to This Course on NetNinja.dev:
https://netninja.dev/p/complete-react-native
🔗👇 Sign up to Appwrite & Get $50 Free Credit:
https://apwr.dev/netninja050
📂🥷🏼 Access the course files on GitHub:
https://github.com/iamshaunjp/Complete-React-Native-Tutorial
🧠🥷🏼 React Course:
https://netninja.dev/p/build-websites-with-react-firebase
🧠🥷🏼 React Context and Hooks Course:
https://www.youtube.com/watch?v=6RhOzQciVwI&list=PL4cUxeGkcC9hNokByJilPg5g9m2APUePI
🔗👇 Install Node.js:
https://nodejs.org/en
🔗👇 React Native Docs:
https://reactnative.dev/docs/getting-started
🔗👇 Expo Docs:
https://docs.expo.dev/
🔗👇 Appwrite docs:
https://appwrite.io/docs
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Net Ninja · Net Ninja · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Regular Expressions (RegEx) Tutorial #14 - Matching a Username
Net Ninja
Regular Expressions (RegEx) Tutorial #15 - Email RegEx Pattern
Net Ninja
Regular Expressions (RegEx) Tutorial #16 - Finishing Touches
Net Ninja
GraphQL Tutorial #1 - Introduction to GraphQL
Net Ninja
GraphQL Tutorial #2 - A Birdseye View of GraphQL
Net Ninja
GraphQL Tutorial #3 - Project (stack) Overview
Net Ninja
GraphQL Tutorial #4 - Making Queries (front-end preview)
Net Ninja
GraphQL Tutorial #5 - Express App Setup
Net Ninja
GraphQL Tutorial #6 - Setting up GraphQL
Net Ninja
GraphQL Tutorial #7 - GraphQL Schema
Net Ninja
GraphQL Tutorial #8 - Root Query
Net Ninja
GraphQL Tutorial #9 - The Resolve Function
Net Ninja
GraphQL Tutorial #10 - Testing Queries in Graphiql
Net Ninja
GraphQL Tutorial #11 - GraphQL ID Type
Net Ninja
GraphQL Tutorial #12 - Author Type
Net Ninja
GraphQL Tutorial #13 - Type Relations
Net Ninja
GraphQL Tutorial #14 - GraphQL Lists
Net Ninja
GraphQL Tutorial #15 - More on Root Queries
Net Ninja
GraphQL Tutorial #16 - Connecting to mLab
Net Ninja
GraphQL Tutorial #17 - Mongoose Models
Net Ninja
GraphQL Tutorial #18 - Mutations
Net Ninja
GraphQL Tutorial #19 - More on Mutations
Net Ninja
GraphQL Tutorial #20 - Updating the Resolve Functions
Net Ninja
GraphQL Tutorial #21 - GraphQL NonNull
Net Ninja
GraphQL Tutorial #22 - Adding a Front-end
Net Ninja
GraphQL Tutorial #23 - Create React App
Net Ninja
GraphQL Tutorial #24 - Book List Component
Net Ninja
GraphQL Tutorial #25 - Apollo Client Setup
Net Ninja
GraphQL Tutorial #26 - Making Queries from React
Net Ninja
GraphQL Tutorial #27 - Rendering Data in a Component
Net Ninja
GraphQL Tutorial #28 - Add Book Component
Net Ninja
GraphQL Tutorial #29 - External Query File
Net Ninja
GraphQL Tutorial #30 - Updating Component State
Net Ninja
GraphQL Tutorial #31 - Composing Queries
Net Ninja
GraphQL Tutorial #32 - query variables
Net Ninja
GraphQL Tutorial #33 - Re-fetching Queries
Net Ninja
GraphQL Tutorial #34 - Book Details Component
Net Ninja
GraphQL Tutorial #36 - Styling the App
Net Ninja
GraphQL Tutorial #35 - Making a Single Query
Net Ninja
Build Apps with Vue & Firebase - Udemy Course
Net Ninja
Updated Vue & Firebase Course (Udemy)
Net Ninja
Vue & Firebase Real-time Chat (Preview) #1 - Intro
Net Ninja
Vue & Firebase Real-time Chat (Preview) #2 - Project Structure
Net Ninja
Vue & Firebase Real-time Chat (Preview) #3 - Firestore Setup
Net Ninja
Vue & Firebase Real-time Chat (Preview) #4 - Welcome Screen
Net Ninja
Vue & Firebase Real-time Chat (Preview) #5 - Props in Routes
Net Ninja
Vue & Firebase Real-time Chat (Preview) #6 - Route Guards
Net Ninja
Vue & Firebase Real-time Chat (Preview) #7 - Chat Window
Net Ninja
Vue & Firebase Real-time Chat (Preview) #8 - New Message Component
Net Ninja
Object Oriented JavaScript Tutorial #1 - Introduction
Net Ninja
Object Oriented JavaScript Tutorial #2 - Object Literals
Net Ninja
Object Oriented JavaScript Tutorial #3 - Updating Properties
Net Ninja
Object Oriented JavaScript Tutorial #4 - Classes
Net Ninja
Object Oriented JavaScript Tutorial #5 - Class Constructors
Net Ninja
Object Oriented JavaScript Tutorial #6 - Class Methods
Net Ninja
Object Oriented JavaScript Tutorial #7 - Method Chaining
Net Ninja
Object Oriented JavaScript Tutorial #8 - Class Inheritance
Net Ninja
Object Oriented JavaScript Tutorial #9 - Constructors (under the hood)
Net Ninja
Object Oriented JavaScript Tutorial #10 - Prototype
Net Ninja
Object Oriented JavaScript Tutorial #11 - Prototype Inheritance
Net Ninja
More on: Tool Use & Function Calling
View skill →Related Reads
📰
📰
📰
📰
Behind a Single "Paste" Button: The Tale of Two Completely Different APIs
Dev.to · Image2
The Django — Snowflake couple… a therapy session
Medium · Python
Port Numbers, In Order: Why the List Has Gaps, and the Best Stories Behind the Numbers
Dev.to · Yuuki Yamashita
Day 97 of Learning MERN Stack
Dev.to · Ali Hamza
🎓
Tutor Explanation
DeepCamp AI