Building for Web & Mobile with Expo

Rate this content
Bookmark
Slides

We know that React is for the web and React Native is for Android and iOS. But have you heard of react-native-web—for writing an app for Android, iOS, and the web in one codebase? Just like React Native abstracts away the details of iOS and Android, React Native Web extracts away the details of the browser as well. This opens up the possibility of even more code sharing across platforms.


In this workshop you’ll walk through setting up the skeleton for a React Native Web app that works great and looks awesome. You can use the resulting codebase as a foundation to build whatever app you like on top of it, using the React paradigms and many JavaScript libraries you’re used to. You might be surprised how many types of app don’t really require a separate mobile and web codebase!


What's included

1. Setting up drawer and stack navigators with React Navigation, including responsiveness

2. Configuring React Navigation with URLs

3. Setting up React Native Paper including styling the React Navigation drawer and headers

4. Setting up a custom color theme that supports dark mode

5. Configuring favicons/app icons and metadata

6. What to do when you can’t or don’t want to provide the same functionality on web and mobile


Prerequisites

- Familiarity with building applications with either React or React Native. You do not need to know both.

- Machine setup: Node LTS, Yarn, be able to successfully create and run a new Expo app following the instructions on https://docs.expo.dev/get-started/create-a-new-app/

155 min
06 Dec, 2022

AI Generated Video Summary

React Native Web allows for building mobile and web apps with one code base. The workshop covers setting up an app skeleton, configuring navigation, implementing responsive design, and adding custom styling with React Native Paper. It also discusses platform-specific functionality and the trade-offs between React Native Web and separate apps. The workshop provides insights into internationalization, secure storage, and choosing the right tools for app development. Overall, React Native Web and its abstractions make development more efficient and enable building for multiple platforms.

1. Introduction to React Native Web

Short description:

Hello everyone! Thank you for joining this three-hour workshop on building for mobile and web with expo. We'll be discussing React Native Web, a way to write one code base for iOS, Android, and the web. I've used this approach to create a real app called Shirley, a to-do list app available on iOS and the web. We'll be building the skeleton of an app from scratch, which you can check out for free at ShirleyToDo.com. It's a great learning resource for React developers.

Hello everyone! Thank you so much for joining. This is building for mobile and web with expo, a three-hour workshop we're going to be doing together. I'm Josh Justas. I'll say a bit more about myself in just a minute.

To start out, I'm going to talk for just a little bit about React Native Web before we jump into the code. So React Native Web is a way to write one code base and to write for three platforms and more because there's lots of platforms you can write for React Native, but particularly iOS, Android, and the web. And that's what we're going to be talking about and focusing on today.

So I've actually used this approach to make a real app in the App Store. It's just a hobby app. I'm not looking to make money from it or anything like that. But it's in there and it's useful and I use it all day, every day. It's called Shirley. It's a to-do list app. Believe it or not, I actually made a to-do list app. There's not enough of those in the world. But I am very picky about my to-do lists and so I decided to make an app to meet my needs. But so Shirley is written and it builds for iOS and for the web. It could work on Android, but I don't have an Android device. And there was one little JavaScript API thing that was needed and so I didn't work through that. But so, so close to having this for Android, as well. It's actually available for free, free account. So if you want to check it out, you can go to ShirleyToDo.com. On web it has a link there to get to the iOS app and the source is available as well. And so we're going to be building out an app from scratch, the skeleton of an app. But if you want to see a real app, you can check out the source there.

One of the things that's exciting to me about this app is it's big enough that it's non-trivial. Like it's got some edge cases and some complex things, but it's small enough that you could totally follow it. Like in its normal React patterns or React native patterns. If you are a React developer, you will be able to follow what's going on in this codebase. So if that's helpful for learning, please give it a check. Fork it. Take out all my stuff. Put your stuff in, feel free. And again, it's free to register. So if you want to register just to see what this React native web app feels like totally feel free to do that.

2. React Native Web Features and Best Practices

Short description:

We'll talk about React Native Web and walk through setting up an app skeleton. Not an intro to React Native, but you'll be able to follow along. Visit the React Native official docs for more details. Stay in touch via the Test Double newsletter for updates and trust us with your email address.

And to introduce things, we're going to talk about what React Native Web is. Then the bulk, almost all of our time, is going to be walking through setting up an app skeleton. The basics of an app to get responsive design and styling and navigation and a good look and feel working. Really, everything you need to be ready to go to start adding application useful features, business logic to your application. Then at the very end, we'll have just a few minutes of discussion on when to use React Native Web. I'll share my thoughts and if anyone else has thoughts, very welcome at that time as well.

A note is that this is not mainly an intro to React Native. So I'm going to be explaining enough if you haven't used React Native before, I'm going to be explaining enough as we go that you'll be able to follow along, but not enough to fully equip you to write React Native code if you haven't before. So the React Native official docs are really great for this, actually. So if you go to this URL, or just go to react native.dev, it's a great intro to React Native. And you'll be able to start from there.

And as a reminder, if you want to get to any of the links that we share here, if you go the workshop webpage that's down at the bottom here or linked in Zoom and in Discord, you'll be able to get the links. And I'm pretty sure they're clickable in the downloadable slides that I have posted there.

Alright, so I work at a consultancy called TestDouble. Is a company improving the world of software? That's what we say. Software is broken and we're here to fix it. So if you've ever been frustrated about software, that's kind of the whole theme of our company is that, yeah, software can be extremely frustrating sometimes and we want to help. So we do consulting, we'll join your team to help you, to level you up, help work through thorny code things and help you as we make decisions together on the code. We can help get apps started from scratch and everything like that. So feel free to hit up testdouble.comslashagency if it seems like we could help you. We work in React, React Native, on the Web, Node, Golang, Ruby on Rails, a lot of different technologies, and we love to help you out. I'd love to join and help you out. A lot of great co-workers that could as well.

So staying in touch on social media is really interesting in the last month, isn't it? Things have been changing and we don't know exactly know where things are gonna go. So Test Double has a newsletter, but even more so now, it's like, who knows what social media is gonna look like in a month. We would love to be in touch with you over a newsletter. And so if you'd like to hear from me or others, if you get benefit out of this workshop, you can go to testdouble.com and follow along. Our company really, really focuses on privacy in your information. We will not abuse that information. It's a newsletter. You unsubscribe works. So please be willing to trust us with your email address if you would like. We will be trustworthy with it. So feel free to stay in touch via the newsletter.

3. Setting Up a Multi-Platform React Native App

Short description:

React Native Web allows you to take your React Native code base and target the web with it. You can build one React Native app for iOS and Android, using a pressable or other button type components. React Native web turns your React Native code into HTML for the web. You don't need React web anymore, just one code base for all three platforms. React Native paper is a library that provides material design for React Native, including the latest Material Design 3. It works on both web and mobile. We'll be using Expo, a framework built on top of React Native, which provides a higher level of abstraction and additional functionality. We'll set up navigation, a component library, dark mode, custom theme, and responsive design using Expo, React Navigation, and React Native paper. Let's get started with the code!

What is React Native Web? It's kind of a weird name that's a bit hard to follow. So first to introduce React Native and even before that for React. So React, as you know, I'm sure, lets you build web applications. And so in HTML on a browser, and hopefully my cursor shows up here for you here, in HTML running in a browser, you need a button element, for example, to have an interactable button. And so when you're writing React code, you use JSX, you create a button element in the JSX and give it all the stuff that it needs. React turns that into an HTML button on the page in the document object model in the DOM. So that's great. We love working in React for our web applications. Maybe your business needs an iOS app and an Android app as well. And so by default, you're building in iOS and on Android using their specific technologies. And so on iOS, you're using a UI button, unless you're using SwiftUI, which things are different, and on Android using a button a view on there as well. So we're building three different apps. So React Native can help make this a bit simpler in two different ways. First of all, React Native, you know, the two biggest platforms for React Native are iOS and Android. And so you can build one React Native app. You can use a pressable or one of the many other button type things in React Native. And React Native, when it runs in your application, runs an iOS application and an Android application. And under the hood, it will turn that pressable into a UI button on iOS or a button on Android. Basically, what's going on natively becomes implementation details there. You have just one code base that covers those two applications. You also get the React programming model and JavaScript. And so many or most of your JavaScript libraries and React libraries will work in React Native as well. So that's two of the benefits of React Native. So now we have two applications instead of three. And both of them are using the React programming model, which is really great. But it would be nice if we could go further. And that's what React Native web allows. React Native web allows you to take your React Native code base and target the web with it. And so you're able to, that pressable that you write in your React Native code gets turned into an HTML button on the web. And so as a result, you don't need React web for this application anymore. That goes away and we have your one React Native code base that includes React Native web that's targeting all three platforms. So now it's not just the shared programming model. It's one code base targeting all three platforms.

I see a question that says is Mewe available for React Native, which is a material UI. I don't believe Mewe itself, that specific library, is targeted for React Native, but we're gonna be using a library called React Native paper. Which is another implementation of Google's material design. That's part of the big, big foundation of the workshop today. And React Native paper works great on the web as well. So if the goal is I want material design, including the very latest Material Design 3, React Native paper will make that available for you on web and on mobile. So you'll get a taste for it over the next couple of hours. Thanks for that question, Jan.

Alright. So this is what React Native web is all about. And maybe that image helps, but you'll get to see the specifics as we go through. React Native web is the name of the npm package. It's titled React Native for web on the page. Which kind of, how do I say it? How do I describe it? It can be used in any React Native project, but there's some setup involved. And so the recommended way to use it from React Native web's docs is through Expo. So you likely know about Expo if you're in the React Native world. If not, React Native is the library provided by Facebook and Expo is a framework built on top of React Native. It's a third party company. And they remove, basically give you a higher level of abstraction so that you don't need to work at the native iOS or Android level. And React Native by default, you're mostly writing JavaScript code, but there is an iOS project and an Android project. And they have their configuration files and their native code and everything like that. And so Expo removes it a bit further, so that even more of the time you can just be writing JavaScript. And they provide a lot of great functionality out of the box as well. So we're going to be using Expo. Expo doesn't lock you in. There's ways to use Expo to pull in native code. There's ways to eject out of Expo to get to a normal React Native app. And so, you know, a lot more information. Expo Docs are great and can fill you in or I can answer questions about Expo. But again, you will get a feel as we go through here together of what it's like to use Expo.

So it's time to walk through. The layout, what we're going to be doing in general, here's the app skeleton we're going to be setting up for an app from scratch that works on iOS, Android, and web. We're going to set up navigation around different screens and make sure that the URLs for those screens work. We're going to be setting up a component library. So pulling in React Native paper, as I said, to get material design. We're going to be setting up dark mode as well so it looks and works great all the way through the application so light mode and dark mode work well. We're going to set up a custom theme as well, so it's not just the out of the box material design, but we get some custom colors to make our app a bit more distinctive. And we're going to implement some responsive design as well. That was one of my biggest challenges getting into React Native was I know how to do responsive design on the web, how can I do this on mobile? So we're going to look into ways to do that. That you're going to fit with your mental model if you're a web developer. And that's what we're going to be setting up. We're using expo. We're using React Navigation, which is by far the most popular and recommended navigation library for React Native. It works really well on the web. And React Native paper for material design. Again, great support on web as well as on mobile. So we're ready to go, ready to jump into the code. So let's get started. I have here the starter app repo. And again, that's available from the web page if you want to pull it down. But I've only done very little so far. It's pretty much the stock out of the box expo app. I just installed some dependencies to be ready. I need my code formatting, so I had to set up Prettier, so it's going to tell me and format everything as I go. So let's confirm that it's running. Here's my iOS simulator and open up App.js to start working on your app shows up. Here's my Android emulator.

4. Setting up React Navigation for Web

Short description:

Expo is preconfigured to run web out of the box. We need to install the required dependencies and add a Babel configuration. We'll use React Navigation for navigation and create a navigation file. Let's get started by creating sample screens and setting up the navigation structure.

Cool, and it's showing up. So the first thing we want to get started, and let me just pull up my little notes here so I remind myself what I'm doing. Hide this. One second, I'm going to shrink this down. I'm going to put the chat over to the side. Great, OK. All right. So Expo is almost preconfigured to run web out of the box. If you… let me stop and restart the server. Just run yarn start to get thing started. And when Expo starts up, it says, press A to open Android, I to open iOS simulator, and W to open web, and you may notice that it's grayed out a little bit. So let's press W and see what happens. And, yeah, so it says, it looks like you're trying to use web support, but don't have the required dependencies installed. So we're given this command to install these dependencies. Just a few other things, React Native Web itself and others. Expo just doesn't want to include those by default unless you're actually using the web. So let's stop the server and put those in. I made a little command here to have them written out. I found I needed quotes around expo-webpack-config and let's just hit Return here. These are gonna get pulled in. It wasn't too slow when I did this before, so I think we should be fine. But once this is the case, that built-in web command that comes out of the box on Expo should work. Or we can do it from the Expo Start menu. Cool. So that's pulled in. Let's start again. The project starts up, and we press W for web. Alright. This is open in a browser, so I'll drag that browser over here. And we get the same app. Open App.js to start working on your app. So this is just the same on all three platforms. So that's nice as a starting point, but it is just a very basic starting point. So we need to go from here to say, okay, cool, we've got our app running in three places. iOS, Android, and web. Where do we go from here? How do we get started? So the first thing that I really wanted to get into is navigation, because I know my app's going to need multiple screens, multiple URLs, and I need to get that working. If we can't get that working, which could be challenging, we're not going to make a lot of progress. So for that, we're going to use React & Navigation. It's the most popular navigation library for React Native. And so I'm going to copy some dependencies here over. All the docs for these tools are really great. And so if you go to their homepages, you're going to get this information. But for this, for React Navigation, it actually has separate packages. And so we need React Navigation Drawer, React Navigation Native, React Navigation Native Stack, and there's a Babel plugin that's needed as well. So we're going to install those. So fun to watch Yarn-installing packages, it's great. And then after that, there's a few more Expo libraries needed as well. And Expo has such a high level of adoption that these libraries have instructions, if you're using Expo, do this. And so in React Navigation's docs, you'll see this information. And we've run expo install. And that runs Yarn add under the hood. But what it does is, Expo has a bunch of these kind of low level libraries that have native code pre-installed. So this will ensure that the versions in your package JSON match what's available in Expo itself. So again, I'm just following the readme library documentation instructions to install these dependencies. And these are written all out on the instructions on the conference workshop webpage. So here's the page if you're curious. So if you go to that link that I sent, you get the full written out workshop here, including any details. So if you miss something and want to come back later, you can walk through that. So this should be all our dependencies needed, but we need to add a Babel configuration as well. And we do have access to Babel in Expo. So let's add this in. There's a couple of plugins to add. Babel plugin proposal export namespace from... And when the latest version of Expo came out, and what came from Expo is super helpful for me is I was running a new issue with this. We found that this Babel plugin needed to be added explicitly. I'm not sure if the docs for reanimated have been updated yet, but we found that that was needed. Reanimated is one of those libraries that runs under the hood that React navigation uses. So a little bit of setup required, but once it's in place, we should be good to go. So we've added this Babel config, and we do need to stop and restart our server. So let's run yarn start again, and we're gonna get started. So it's started back up. I'm gonna start, hit W for web, because you can't just reload the page that the web app is on. You need to start it because web pack hasn't started by default. But now that does reload and that shows up just fine. All right, so we need to begin configuring our navigation structure. So the way I like to do that is with just a file called navigation. It's just a convention. I mean, there's so many other things we're gonna walk through today. You could set up differently if you like. I'm just showing one way to do it. But it's a way that works. So I'm gonna create a source folder because I like to do that. I might create a navigation. See if I can type as we go through here together. So in this navigation file, there's a good amount of setup that happens here to get our initial react navigation screens working. So let's get started. First of all, I'm gonna create a couple of sample screens that are just gonna kind of be placeholdery, but just enough to give us a try. It's gonna be the home root component here. And here we're gonna say constant navigation equals use navigation, that is provided by react navigation native to way to get this navigation control object. And I'm gonna return just enough elements on the page here to see the screen.

5. Setting up Navigation

Short description:

We import the 'text' component from react native and use it instead of div and paragraph tags. We use the latest 'pressable' component for buttons. We navigate to the 'home detail' screen when the button is pressed. We create a 'home stack' and add the 'home route' and 'home detail' screens. We create an 'other stack' and add the 'other' screen. We combine the stacks in a drawer navigator to allow navigation between screens. We export the navigation component using a navigation container.

We're gonna say text, and we're gonna import that from react native. So this is one difference with react native if you haven't used it, if you've only used a react in the web before is instead of just using div tags and paragraph tags, you have a text component you need to import from react native. And I see my editor has done old style imports. So let's do yes, six ones just what I prefer and I think I sometimes get errors with that.

Okay, next we're gonna have a pressable which is the latest version of button type component for react native. It looks like react native web had one as well but you do just import these from react native like default, we're gonna put text inside the button that says go to detail cause we want a detail screen and then we're gonna do on press navigation navigate, home detail. So that's one of the ways that you can navigate with the react navigation libraries. We have a home root screen here and we're gonna go to home detail. Save, make sure that formats that's fine.

All right, let's create that home detail screen now. It's gonna be pretty similar. So I'm gonna copy and paste this just to save a little time. We still need navigation, but it's gonna be home detail. And this button is gonna say navigation.pop. So because we have a stack navigator where it's like we're pushing different screens onto each other, pop says, go back to the previous screen. And we'll see that working, we give it a try. If you've done react native with react navigation this will be familiar. This is all normal react native approach. We're gonna say back to home route. So now there's two screens to go back and forth between each other. Let's create one more screen. Another one that's the root that's not related to the others. Stacks other route. Alright, we got three screens. Now we need to use a stack navigator. And again, I'm just talking about concepts here but we'll get to see them running in just a second once we started it up. A stack navigator is two different screens where we can pop things on top of each other and then we're gonna have a way to move back and forth between them. So let's say home stack equals create native stack navigator. Get that imported automatically and then we create home. So this is all the home screens including the home route and the home detail. So remember turn. So the API here, and I would not remember this off the top of my head. I would need to check the docs but it's home stack navigator. So that's the surrounding navigator here. And then we create screens under there. So say it's homestack.screen. Name equals home route. Component equals. Home route. And options equals title home. You'll see how the title is used. So really this is connecting together, home route which is just a normal react native component. And the stack navigator that comes from navigation. That's what's connecting these together. I'm going to add one more screen. Very similar it's the home detail with the home detail component. And we're going to say home detail in the title of the screen. So that's good. I'm going to create another stack for the other screen. Other stack function other. Let's just change all these. Other stack. And we only have one screen in that stack. But having it in the stack is still helpful. So, so this is another stack that's going to allow us to access that other route screen. So now we have two different stacks but we need to put those together. We're going to combine those in a drawer and a drawer slides over from the side to allow you to navigate in a natural way there. So we're going to create a drawer. Create drawer navigator, function navigation contents. And then here, we're just going to return drawer navigator. And that we're gonna have a drawer screen. So this, the screen abstraction works here as well. This one's called just home by itself. Component is home. We're going to have an other, if component is other. So if you look at this altogether, what we have is a drawer at the top level that has two screens that are at home and other. And a drawer is gonna allow us to navigate between them. And then home and other are each stacks that have one or more screens underneath them. So that's all the wiring together of the navigation that happens.

There's one note, by the way, if you are coding along with this in the notes for the workshop, if you get an obscure error with react navigation, I was getting this at some point where I had needed to use a prop called Use Legacy Implementation. I just Google around for the error I was getting and that came up on helpful GitHub issue answers. That has since gone away. And so I don't feel, it doesn't seem like I need that workaround anymore. But if you run into mysterious errors working through this yourself, use Legacy Implementation as a prop that might help you. But let's see, maybe we'll be okay today and don't need it.

So there's one more thing we need to do in this navigation file. And this is where we're gonna actually export from the file. I'm gonna create the navigation component that's the main point of this. And here what I'm gonna do is a navigation container, and in there we do navigation contents. Now that seems kind of weird, like why are we doing that? Why don't we just inline these navigation contents right here? And what I found, we'll actually see a bit later in the workshop. Well, it's having trouble finding navigation container to import it. All right, well, let me just add that import explicitly. You'll see a bit later in the workshop why I separate these out. Basically I'm gonna need this to re-render a lot based on a custom hook. But what I found is that navigation container does not want to re-render, that causes problems, that actually cause an error that crashed my app. Because the browser in some cases was wanting to check that it seemed like something was wrong. So this separation helps to avoid unnecessary re-renders that were causing an error in some cases. But we'll see more about that a bit later.

All right, so now we have this navigation component with all these screens, these multiple levels going on, but we need to hook it up. So let's put it into our app component here.

6. Configuring Navigation and URLs

Short description:

We remove unnecessary styles and replace the contents with status bar configurations. The navigation is set up for iOS, Android, and Web, with different animations and styling. We configure URLs using the Linking object, specifying paths for each screen. The web app refreshes automatically, and the URLs change naturally as we navigate. Deep linking is also supported on mobile.

And what I'm gonna do is remove the styles because we don't need those. And I'm gonna replace the contents with this, status bar style equals auto, status bar component just allows us to configure what shows up on mobile for the status bar. Now I'm gonna pull in the navigation. That's pulled in. Looks like all those inputs are not needed. So now our app is wired up to use the navigation we set up. All right, so we should be set to give this a try. So let's, there's a lot of coding to set up the basics of navigation. Let's see how it looks. I did, I restarted Metro, so I need to refresh. It's loading up. All right, so on iOS here we see we've got some title bars. We have two title bars here. That is not longterm intentional, but that's an issue that we'll work around further on. Home route is shown. We have a Go To Detail. It actually isn't styled as a button because a pressable doesn't do that by default, but React Native Paper will help us with that a bit later. When I click on Go To Detail, I'm taken into this detail screen. You can probably see on the video a nice iOS like animation that happens there, and I can click back on this Home navigation link, or I can click on the button back to Home Route inside the view to go back. Now if I click on this little menu hamburger here, the drawer slides up. This is the drawer with Home and Other configured. When I tap on Other, the Other screen, other, other, other, shows up, and I'm able to go back to Home. I believe if I go to the detail, it'll remember that, so if I go back, yeah, I'm still under Detail there, so it remembers the state of the stack under the Home screen. Let's try Android. Reload. Got my screen, go to Detail. You may notice that the animation here is different. So React Navigation is set up to give an Android natural animation there. We can still from the drawer, go to Other, and go back to Home. Now let's check out Web. I've got my screen, it looks the same, we're on the Web. I can click on Go to Detail. Notice that there's not actually an animation in this case. That may either be because of Web capabilities, or maybe that just happens to be as natural on the Web. There is an animation when the drawer slides over from the side. I can still go to Other, go back and forth. I think this arrow is different on the platforms as well, let's see. Yeah, so this is a very, iOS natural styling with blue there by default. Let's see on Android, on the Detail as the arrow matches what's on the Web. So there's differences here in React Navigation as it matches platform conventions. And we're gonna swap out all this default API with React Native Paper a bit later, but everything is working on all three platforms. Minus this bar thing. We're gonna come back to. The first thing I want to work on next is URLs. So check this out. On the Web, when I click on Detail, I go to another screen, the URL is the same. Or if I go to over the Other, the URL is the same. And that's not what we expect on the Web. On the Web, we expect the URL to change and we'd expect to be able to use the back button to get back to previous screens we were on. Now React Navigation has good support for the Web by default. We just need to tell it what URLs to use. And we do this with an object called Linking, so let's configure this. Again, I'm checking my notes here because I would not remember this off the top of my head if I didn't, but the docs are really good. In this Linking object, we have a config. In the config, we have screens, which configures our root level screens. We give it the same keys that we use above, Home and Other. It corresponds to Home and Other up there. And now we configure each of these. So under Home, we say, what is the path for the home screen? We'll put that at the root of the application. Then we have nested screens underneath there because that is a stack navigator that has screens underneath it. So we have those screens, which are called home root and home detail. So we're gonna put those in. And for each of these, at this point in the nested tree, all we need is the URL. So we're gonna put home root directly under that parent path. And home detail, we're gonna put it under slash home slash detail. That may be a bit unexpected, but the reason for this is just like, conceptually this is just like being a slash home, but for the very root of your application, typically you expect that just to be at the root path. So I leave that as the empty string. For other, we're gonna give it the path of slash other. That's how to get to the root of that stack. And there is a nested screen under there, even though there's only one, it's called other root. We're gonna just say that's directly under slash other. It's not further nested. So this is our linking config. What is this? It sets up the URLs and the nested URLs for all the places throughout our app. The place we hooked this up is at navigation container. So we say linking equals linking. If I can type. All right, let's save and let's see the result. Notice our web app, as you'd expect on the web, it refreshes automatically and we're good to go. When we click on go to detail, now we get a path where under slash home slash detail. When we go over to other we get slash other. So we're getting URLs that change naturally as we go. There's something else though. Let me show you this. If we go to other and we reload the browser, we are taken right back to the other tab. So that makes sense. That's natural, we expect on the web. We can link directly to a specific screen. And incidentally React Navigation works with deep linking on mobile as well. My coworker, Louis, is working on a blog post on this right now.

7. Audio Issues and Reload

Short description:

I will add the information to the conference workshop web page once it's live. If you're on the home detail page, try to reload from there. We don't have a back button anymore. There seems to be an audio problem for Ez, but others have reported that the audio is okay. The workshop is recorded, so you can access the recording later. Feel free to ask for help in the discord channel.

So I will add that on the conference workshop web page afterwards once it's live. It should be soon. So if you're on the home detail page, let's try to reload from there. And notice something surprising, we don't have a back button anymore. Cool, oh, I see in the chat, Ez is having a problem with the audio. I'm sorry to hear that, Ez. So Paolo, and replied, yeah, several have replied that the audio is okay. So I'm glad to hear that. Ez, I'm sorry about the audio. You may be able to disconnect and reconnect. That may help. This workshop is recorded. So in a worst case scenario, you will be able to get back to the recording afterwards. But I'm sorry about that. You could ask in the discord as well. I may be able to get some help in there. Thanks for collaborating on that, everyone.

8. Configuring React Navigation Stacks

Short description:

On the home detail page, the back button is missing from the title bar, and clicking on 'back to home route' doesn't work. React navigation stacks work differently from the web. We need to use a configuration to set an initial route name. By setting 'home route' as the initial route, we ensure that we always start from there. Now, when we go directly to 'home/detail', we see the back button and can navigate back to home. React navigation solves the complexities of mobile and web navigation, allowing us to build apps that work seamlessly on both platforms.

All right, so on this home detail page, when you reload or navigate to home detail from scratch, notice there's not the back button in the title bar here anymore. And if I click on back to home route, that actually doesn't work either. So what's going on here? What's going on is that the way these react navigation stacks work, it's not quite like the web. The idea is there's a stack that's stateful and mutable, and you're adding things onto it. So when we navigate it to home detail, there's nothing that says, hey, you always start from home route. As far as react navigation knows, home detail is just the one screen on this stack that we want. And so, what we need to do instead is use a configuration. Luckily, react navigation helps us out with this. There's a concept of an initial route name, and we can say home route is the initial route for this stack. What that means is, no matter where you navigate into via URL or something else, you'll always start with home route on the stack. So let's save and reload. So now when we go directly to home slash detail, we see the back button, and we're able to go back to home there. So that is natural and allows us to navigate around the way we would expect. It is important to call out because, mobile and web navigation is not identical. That's why I'm so glad that react navigation exists, and that the maintainers are investing in it to solve these hard problems. And so if anything seems complex to you in react navigation, it's because it is inherently complex. And the maintainers, I feel like are doing a great job finding high level of abstractions like we're doing right now to allow us to build apps that work great on mobile and on web with deep linking and everything like that.

9. Enhancing App Look with React Native Paper

Short description:

We've successfully implemented navigation for our app and made sure it's working. Next, we want to enhance the look of our app by installing React Native Paper, a component library that provides great styling for material design. We'll start by wrapping our app with the Paper provider and then proceed to style the navigation drawer to fit with material design. We'll create a custom navigation drawer component using React Navigation and React Native Paper, and wire it up with the necessary props. This will give us a styled navigation drawer with highlighting for the items. React Native Paper goes beyond Google's Material Design and offers additional helpful concepts. We'll use the drawer.item component to render the navigation drawer items, and customize it with the necessary props. Finally, we'll implement the is selected function to determine if a route is selected based on its index in the navigation state.

All right, so we've got navigation for app working, let's just reload on mobile to make sure we haven't broken anything. When you are developing for three platforms, and you wanna make sure that things are working, so yeah, reloading, we can still go to detail and we're good to go, we can go to other, and we're set, go to detail, go back, we're good. Alright, our navigation is in place, and this is gonna serve us to the rest of the workshop.

Up next, we wanna make our app look awesome. Because even aside from the double toolbar is there, it's looking pretty plain. This is not a button, this is just text so we need to make it look better. And when I'm building apps, unless we're for a lot of professional apps, I have public facing things, things that they wanna hire consultancy like us. There's dedicated designers that are given a specific visual designs. But when you're doing a side project, or you're doing a MVP or proof of concept, or you're doing something internal for your company or for employees, you may not want to style everything from scratch. And so it's great to have a great looking component library that you can pull from. And React Native Paper is a really, really great one. And it works great on the web as well. So let's install it. It's yarn, add React Native paper. Actually, just this morning version five was released. So we're gonna jump straight into the new Breaking Change version. Previous versions of this workshop, I have been using the release candidates and so things are still stable. But we are as of today, as of six hours ago, we're on React Native Paper, 5.0.0. So that's very exciting to be on the leading edge. So we install that and we're gonna start the server again. You don't need to restart the server every time you add a dependency, but sometimes you do. And so, plus, I just have one terminal here so I'm starting it to get it installed. So now in the app, we need to wrap it with a provider as you're probably used to, import provider as paper provider from React Native Paper. Paper provider. So, this is now available and we're gonna be able to use this provider for theming coming up a little bit later. But now our app is ready to use React Native Paper. Vicky had, usual to ignore peer depth's warnings? Did that come in the installation? Yeah, you know honestly, I have seen these warnings in React Native in general and in Expo in particular. And I have generally not needed them. In particular React Native Paper doesn't have an installation step the last time I checked the required installing React Native vector icons. I think that may differ between Expo and React Native CLI. So, for warnings like this, I would check the installation instructions for the library that you're using. I think what's going on here is that Expo automatically includes React Native vector icons, but maybe not in a way that Yarn can see. So, yeah, what we're going through today, ignoring these peer warnings has worked for me. You or others may know better, and so feel free to investigate the details of the NPM ecosystem. But yes, it is intentional to not do anything about this warning here. Thank you for asking, Vicky. All right, we got a React Native Paper and so there's a lot in our app to style and theme with paper for material design. So, let's see where I said... I'm gonna start with the drawer first because it's pretty straightforward. So, out of the box with React Navigation, I'm gonna reload. We get this nice navigation drawer and it gives us even this highlighting for these drawer items. We want to style this to fit with material design, so let's do that. The way we can do that... I'm gonna create a components folder because that's something that I like to do, and in there, I'm gonna create a new file. We'll call it Custom Navigation Drawer. So, let's code out our custom navigation drawer and React Navigation and React Native Paper work really well together. They both have a very high levels of adoption and so they work well. So, let's get this working, I'll show you how. In the Custom Navigation Drawer. It's interesting that even though we're using these great libraries with great abstractions, there's still a little bit of wiring needed to put this together. Incidentally, if you don't wanna code all this yourself, you can use the repo from this workshop as a starting point for you to code off of yourself. You're totally welcome to. We're gonna take in the props for the Custom Navigation Drawer. This is something we're gonna pass to React navigation for it to use to render the drawer. In here, we need to pull out a state and navigation from the props. We do need all the props as well though. That's why I kinda take them that way. Let's come back to this conditional in just a second. So, we're gonna return what's called a drawer content scroll view. This is provided by React navigation and this gives it some of the logic needed to do the kind of drawer coming in and out and scrolling. And here, so in state, the navigation state, there is a state routes object. It looks like my language server is not noticing it. So, we are giving here a list of routes. And so, we can dynamically have this drawer work off of those routes to render things up. So, we're gonna map over these. We're gonna get the route that's passed and we are gonna need the index as well. So, in here we have, next what we're gonna use is a drawer from React Native because React Native Paper has a concept of a drawer. Interestingly, I think React Native Paper goes beyond what's in Google's Material Design and provides a lot of other helpful and useful concepts as well. So, I love how full featured it is. Whenever I need to show something in my app, usually React Native Paper has something to help me out. So, it has the concept of a drawer. So, we're gonna use a drawer.item to render out a navigation drawer item. And there's a bunch of props for that. We are gonna need a key because it's React and we're looping here. So, we can use our route.key. Again, I don't remember this off the top of my head. I've just used example code and looked into the APIs for these tools to see what properties are available. Label is gonna be the text that shows and we're gonna use the route name. That's gonna work for our purposes here. Just as I was working, I created this workshop after real applications that I created. And what I found is that having an accessibility label is helpful here for screen readers for our app. So, I'm gonna go ahead and put that in because you might as well add an accessibility there from the very start since I know about it. A drawer item has the concept of active, whether it's selected or not. So, we're gonna specify that. Active comes from, and I like to pull non-trivial logic, even sometimes trivial logic out of my JSX. So, let's create an is selected function so we can say, is the route at this index selected. Now, let's implement that. Const is selected. Pass an index. And we say, if index is equal to state.index, so then navigation state, React Navigation passes us, tells us the index of the selected screen that we're on.

10. Implementing Custom Navigation Drawer

Short description:

We implemented the custom navigation drawer using React Navigation and React Native Paper. The drawer has a Material Design look and feel on all three platforms: iOS, Android, and web. React Native provides built-in styling, and there are other libraries available for mobile and web development. Let's move on to styling the header and removing the duplicate header.

And so, I just pulled that out. You could inline that, but I like giving it a name. I think it's helpful for workshops or for future code. We also need an on press to do something once we click this navigation item. And we're gonna say navigation.navigate, route.name. So just whatever route in the drawer we're going to there, we're gonna navigate to it this way. I think we're good there. So this should implement the custom navigation drawer with everything we need. Again, we're using some of React Navigation things they provide. We're wiring up a React Native paper for the look and feel. So let's see that in use. In navigation, we need to wire this up. So let's find our drawer. Here's the drawer we created, the drawer that has those two screens, and we're gonna configure it now. So we're gonna say for the drawer navigator, the drawer content, and my language server is seen out there, which is nice. We're gonna say custom navigation drawer and import that. So we're telling React Navigation, don't use your automatic built-in drawer with the default one. Use my custom one to render out these screens. But I have hard-coded these screens underneath, React Navigation's gonna pass them to me so I can use my dynamic logic here to render those out. So let's save and see how this drawer looks. Pull out the drawer, and now we have a nice, big, round, tappable purple. This is Material Design 3, which is included in React Navigation paper version five. So this is now custom paper-looking feel for our drawer. Let's check our other platforms as well. Ooh, our app has disappeared on Android. Hope that isn't an indication of an issue. All right, we pulled the drawer and we've got that material design look there as well. Let's check on the web. I'm gonna press W again to relaunch webpack. Go over here, pulled the drawer. And we've got Material Design on the web as well. So on all three platforms, you're gonna have a nice Google material design. For Expo or for React Native Web, you don't need to use Material Design, of course. All of React Native's built-in styling is available as well. And there's other libraries for React Native that support mobile and web as well. But if they didn't, you would need to make that work. So, yep.

11. Implementing Custom Navigation Bar

Short description:

Let's work on the header and style it to match Material Design standards. We'll add a custom navigation bar component to customize the navigation bar's look and feel. JavaScript is used instead of TypeScript, but TypeScript support is available. The language server pulls in TypeScript typings for auto-complete and editor hints. Auto-reload works well in React Native, but manual reload is possible using simulator-specific tools. The shake gesture on iOS and 'R, R' on Android trigger reload. Implementing accessibility is important for users with temporary or permanent disabilities. We add a back button and show the title of the current screen. A hamburger menu on the right side toggles the sidebar. Material Design icons are available in React Native Paper. Removing duplicate headers ensures a clean layout.

All right, so now let's work on the header. Let's style the header to match Material Design standards. And let's get rid of this duplicate header while we're at it, as well.

I'm gonna add a component called custom navigation bar. Now let's implement that. Like with the drawer, this is something we pass into React navigation to customize the look and feel for the way it renders the navigation bar, but it gives us props, then it gives us logic that we can work off of. Incidentally, I am using JavaScript here, rather than TypeScript. All of these tools, as far as I know, have great TypeScript support like React and React Native 2, in general. So you can use TypeScript with all of these, as well.

Biggie says, off topic, how are your language servers working? Is it based in types of definition files or something else? Yeah, so I am very limited. Again, I'm not using TypeScript, but JavaScript. I use Sublime Text, I'm very old, and so I don't use Visual Studio code. Of course, Language Server works great in Visual Studio code, as well, but it also works in Sublime Text and other editors. React and React Native and all these libraries have great TypeScript typings built in. And so, the language server is automatically pulling those in and using those for auto-complete and for editor hints, even though I'm writing JavaScript, rather than TypeScript. Demetri says, which shortcut are you using for reloading the app on Simulator? Yes, so, a lot of times, and some of the maintainers of React Native, at React Native EU, asked me about this and said, hey, you know, auto-reload works really well in React Native now. And so, I am trying to stick with that and to let the app automatically reload itself whenever possible. But when you do need to reload it, like, for example, when you stop and restart Metro, is actually Simulator-specific tools. And this is in the React Native documentation, expo documentation. It's the shake gesture on iOS, which is Command, Control, Z, on the simulator to pull up the expo menu and click Reload. On Android is different. It's R, R, so you press R, R on the keyboard, and then that reloads. There's some other commands that I forget to actually pull up the expo menu, and then in a web browser, you just click Reload. So, it is a bit unfortunate that that's inconsistent across the platforms, but it is part of life with React Native. But if you know it for React Native, it'll work for all of these tools as well. You're welcome.

Custom Navigation Bar. Let's implement it. We need a navigation prop, Options prop, and the back prop, and we'll see why shortly. Here, we're gonna go ahead and return. App Bar. So, App Bar is also provided by React Native Paper. You'll not be surprised to know that that's part of what it provides, that's one of the most recognizable things, I think, about material design. So, we have an App Bar header.

Underneath here, so there's a few different things. First of all, Back Button. Now, I only want to render the Back Button if there's something to go back to, and the Back prop is only present when there is something to go back to. So, I'm gonna do this. So, only when Back is present, when it's truthy, do I render this Back Button, and there's an App Bar.Backaction, specifically BackAction there. We do need to implement onPress for it, and it's gonna be navigation.goBack. There's just passing that function and directly makes the Back action work, and we do need AccessibilityLabel. That's not provided by default, but I wanted it to say back for a screen reader. Incidentally, as a side note on Accessibility, I had learned about it over the years, but about a year ago, maybe more, I started having pretty significant wrist pain. It was enough that it was hard for me to go all through the day typing, or even use my phone for an extended period of time. And so for a while, I needed to use voice commands for typing and voice commands for using my phone. IOS calls it Voice Command or Voice Control. I can never remember which one it is. If your app works for a screen reader where there's text versions of things on the screen, it works for Voice Command, Voice Control as well. And so I found through that which apps were easy to control with my voice and which were not. And for my own app that I was maintaining, I looked into ways that I could make it more accessible so that I could use it. This was really great for me to learn more about Accessibility as well as, I hope, increase in empathy for others. And so I try to focus more on the Accessibility of my apps now. And so if you experience any wrist pain, number one, take care of your wrists. Look into that, get a doctor's help, chiropractor's help. But then also let that flow into making your apps accessible. It is important, and it's not just people who have a permanent blindness or other kinds of disabilities. There's temporary ones like me. Thankfully, my typing is better now. I got some good treatment that really helped, but I didn't know if that was going to happen or not. And so, you know, make your apps accessible for the sake of people that have permanent or temporary or situational disabilities.

All right, so we have the back button here with accessibility. Next, we always want to show the title of the screen we're on. We're going to say appbar.content. Again, this is not something that I remember, but just checked in the API has had a set up this navigation. It's options.title. So the current navigation item we're on, we get the option score including that title that I've specified back over here. So I get that title in. And then also we have appbar.action. What I decided, I don't know if this is material design standards or not, but for my app, what worked is to put a hamburger menu on the right-hand side to toggle out the sidebar. That way the left-hand side is available for the back action if we needed, but the right-hand side is the menu there. So we're going to say icon equals menu. Material design icons are included in React Native Paper. They're available. It's given an accessibility label of menu as well, so that is available for screen readers and we need to implement on-press. Navigation.toggleDrawer, so that's a function in the drawer navigator that allows us to toggle the drawer. This I think implements the custom navigation bar. So now we're going to save and put it in the place on here. So for each of our stacks, we need to put it in and let's see here. It's homestack.navigator, screen options. So a lot of these options in React Navigation are configurable. We're going to say header is customNavigationBar. And we're going to copy and paste that for the other navigator as well. And for anything like this, where I'm duplicating things, of course in your application you could extract out that duplication. One of the great things about React is it's very easy to extract duplication because it's just JavaScript and JSX. For my sake, for the sake of demoing this, and even for my side project, it was more straightforward just to put this duplication in for a few places. It was not a big deal. All right, so we save this. One more thing is we want to get rid of the duplicate headers as well because the drawer adds a header, but our individual stack navigators have headers as well. So we don't need the drawers navigator. So let's configure the drawer to remove that.

12. Implementing Dark Mode Support

Short description:

We've implemented navigation for iOS, Android, and web, with headers, menu buttons, and back buttons. The app has a nice look and feel, following material design principles. Now, let's explore dark mode support. React Native Paper provides great support for dark mode. We can enable dark mode in the simulator settings for iOS and in browser developer tools for web. However, dark mode doesn't automatically apply to the app on mobile. We need to enable the 'automatic' user interface style in Expo's app.json and reload the app. Now, the header shows up in dark mode, but other parts of the app still need styling. We can create a screen background component to handle dark mode styling. By using the theme from React Native Paper, we can dynamically set the background color based on the current theme. This component can be easily wrapped around other components to provide dark mode support. Let's add the screen background component to our navigation screens to address dark mode styling for the entire app.

We can say screen options for the drawer, and we can say header shown false. So let's save this and see what we got. So you can see that my app is, as I'm just making changes to the JavaScript, the apps on all the platforms are automatically reloading, which is really nice, really efficient. So let's check out iOS first. You see, we just have one header at the top and it shows up this way. You may be surprised to see that it's just white because a lot of material design apps we've seen there's a themed color there, but this is the difference if I'm remembering right in the latest material design three. And we'll see some changes as we go along. But so that header is there, there's just one header. That's nice. We've got our menu button on the right-hand side, we click that and we can toggle the drawer. And we go to the detail screen, the back icon shows up on the left and we can go back. All right, let's check on Android next. So we've got home again with platform differences here, React, React Native Paper I think is responsible in this case, unless there's just a bug in my code, but I think it's intentional. There's differences where on iOS, you expect the title to be centered, on Android you expect it to be on the left hand side, so React Native Paper is handling that difference for us to get closer to platform expectations. We still have the back button here. Notice that is a different back icon, which I believe is, so it relates to what's platform expectations, and we still have our menu icon here to pull up the menu on the side. And if we go to web, we can see, we're on the root here, go to detail, we get the back button, and we have our menu icon to pull out the drawer from the right hand, the left hand side. So this is really nice. We've already got a nice look and feel here. Yeah, we've got material design, but the next thing is, what about dark mode? Really awesome, mobile apps, and more and more on the web, but with mobile apps, it's very commonly an expectation to support dark mode, not always done, but that really gives you a lot of polish. And if you use your phone in the dark, like me, you appreciate dark mode. I like to switch it throughout the day to test out my apps to make sure they work in light mode and dark mode. And React Native Paper has great support for it. So let's check out what works. We're gonna pull out app here. What we can do on iOS is to go into settings in the simulator. It's actually on the simulator under developer menu, which is kind of weird. We can turn on the dark appearance. Now we can switch back to the app. So by default that's showing a just normally. Oh, I see I have a typo in home detail, but that's okay. Incidentally, I haven't actually looked into in the Android emulator, how to go into dark mode. So we're not gonna do that for the sake of the demo here and for expediency, but you can do that in there as well. Someone in my last workshop, let me know that in browsers, developer tools, you can switch on dark mode. A lot of you might be using Chrome. I love Firefox. Firefox is really good. Please support the open web by using Firefox. Try it out, it's super fast right now. And in Firefox and Chrome Dev Tools, there's an option to simulate dark mode. So you can click on that to go into dark mode and you could also go into your OS settings if you'd like to see it. We can see here that the header automatically changes the dark mode on the web, but it doesn't on mobile. So why is that? Let's dig in. First, there is an Expo config. So in Expo's app.json, there's a configuration that says user interface style light. And for some reason, they don't automatically let you switch into light and dark mode unless you decide to choose to enable that. So we're gonna choose that, automatic. We save that. And then we do actually need to reload from scratch in Expo. So we'll just click reload. And now we can see that the header shows up dark. Other stuff is not and we're gonna need to style that, but we at least see some change coming through. Basically, Expo doesn't let your app see the dark mode setting unless you enable this permission. Let's just see it switch back and forth. If we switch dark appearance back off, we can see that the app switches. So it's now dynamic, so that's nice. Just like on the web here, it's dynamic. So dark mode is showing up for us, but now we need to get other parts of our app styled to address dark mode. So, one of the things is. So, you know, the app bar is provided by React Native paper. And so it supports light and dark mode by default. But the background of our app is just a view, it's just nothing in particular. So we need to add dark mode support for that. I found in my app, so what's helpful is to create a screen background component. It's just a wrapper that handles dark mode. So let's create that. And this will show you how to hook into React. Yeah, React Native Paper. Because we don't wanna use React Navigation's light mode, dark mode setting directly. Ideally, we just want React Native Paper to tell us, hey, what background color, what text colors should I use, and style from there? So we're gonna be able to do that. The screen background, let's take in style to allow it to be custom styled. We're not gonna use that in the workshop, but that was just something that I found was helpful. Anytime you have really reusable React Native components, allowing a custom style prop is generally helpful. So now we're gonna get the theme. We're gonna use theme from React Native Paper, and that gets us the current theme. Which includes, it's gonna be dynamic based on whether we're in light mode or dark mode. From there, I'm gonna say base style. So aside from this specific style that gets passed in by the user, what is the base style of this component? If you haven't used React Native, these objects are used for styling in React Native. They're inspired by CSS, but they're not CSS and not identical. We're gonna say flex1, which basically is React Native's flex box to fill the screen. It's important for a screen background. And then we're gonna say background, backgroundColor is theme.color is.background. So give me the background color of the current theme including light or dark mode. Then we're gonna just return a view, React Native view style equals base style, and then apply the style overrides, if any, and then render the children. So this is easy for wrapping around other components. So we've got our screen background. Let's put it into place in navigation. We can just pull it in here, a screen background. So that's gonna wrap our home root screen, our home detail screen, and our other root screen as well. And again, if you found this is needed for absolutely every screen, you can remove that duplication yourself in your own code.

13. Styling Text with React Native Paper

Short description:

React Native Paper provides a text component that is automatically styled for light and dark mode. By switching to React Native Paper's text component, we can easily achieve white text on a black background in dark mode and black text on a white background in light mode.

So let's save, and we can see in the background, we already have a black background, or dark, it's not quite black, because you may be able to see the black text on top of it. So that's not ideal, we're gonna need to change that. But we are getting this dark background that actually matches the title bar. Let's check on all three of our platforms. This, oh yeah, Android we don't have dark mode on, so we'll just not worry about Android for right now. Yes, so we've got our background being styled. But what about the text? Now the text is always black whether we're in light or dark mode. Well, React Native Paper provides a text component that is automatically styled for light and dark mode as well, as well as other settings within the React Native Paper theme. So we can just switch navigation here to import text from React Native Paper and use that instead. Now when we save this, we get white text on a black background. And if we switch back, we can see it's black text on a white background. And I'm saying black and white, it's not quite necessarily exactly white or exactly black, but it's the dark color, the light color. We're getting some switching here. So that's really great.

14. Customizing Drawer and Theming

Short description:

Let's implement the background color for the drawer using the scroll view. We'll define a scroll view style object with the background color from the theme. By using the useColorScheme hook, we can determine the current color scheme (light or dark mode). We'll create a custom theme using Material Design 2, which allows for easier theme customization. Material Design 3 requires more configuration to customize colors. We'll handle light and dark mode ourselves in the custom theme. In the next step, we'll add coloration to the theme. We'll create a new file called Used Custom Theme and set up the theme to use Material Design 2. We'll handle light and dark mode using the useColorScheme hook. We'll default the color scheme to light and return the appropriate theme based on the color scheme.

All right, so now let's take a look at the drawer. Okay, so the drawer, it looks like the actual, well, maybe that text color is changing for light and dark mode. Let's see. Yeah, check it out. So the, because these navigation links chain are provided by React Native Paper, they are changing styling accordingly, but not the background. So let's get that implemented as well. Instead of using screen background, we're gonna do something a bit different on the custom navigation drawer. And I'll show you why. Well, I won't show you why, but it's basically, it's the scroll view itself that I wanna style with the background color because that element's already there and that works well for scrolling. So I'm, you know, maybe there's another way to reuse that same screen background, but I'm gonna use the scroll view here. So we're gonna pull in the theme again, use theme from React Native Paper. Then what I'm gonna do is define scroll view style, a style object for the scroll view. And again, we're gonna set the background color theme.colors.background. The way the color changes is that the use theme hook causes your component to rerender when the light mode or dark mode changes that automatically triggers for you. So then in the drawer content scroll view, we're gonna say style equals a scroll view style. Oh, I see that I'm missing something as well. These props that came in from custom navigation drawer that was supposed to go to here. So let me include those. Clearly it hasn't broken anything obvious, but it's important to pass those along. So now we have a scroll view style. We can pull it. It looks like the automatic reload dismisses the drawer so we can pull it back out. And now we have a drawer that has a nice background. Notice that it's actually the same background color as the page, but when the drawer comes out, the other part gets dark and it animates in. It gets a little bit darker so that we can see a contrast of the drawer and the rest of the page. And then if we switch into light mode, we have a nice look as well. We can see this being darkened a little bit differently. Let's make sure this works on here. I don't think I needed to reload there actually. Yep, so the drawer looks good on iOS as well.

Vicky asks, sure you wanna spread all props, not the rest from destructured object? I believe so. I think this came out of the documentation for React Navigation and how to make a custom navigation drawer. It's possible that that's wrong. I mean, it doesn't make sense, when I think about it, that a scroll view doesn't necessarily need navigation and state. So really, I may be doing something unnecessary, but the React Navigation docs will be helpful in that regard. So if any of you are doing this yourself, check the React Navigation docs. They'll have information for you. But yeah, clearly it wasn't breaking anything immediately, at least in my case. All right, so now we have pretty good light and dark mode all the way through everything we can see right now. But the next thing is though, our colors when we switch to light mode so we can see it. So we have the default purple that is default for React Navigation paper. And that looks good. But, it would be nice to give our app a bit more of a unique visual identity. I'm already using React Native Paper and Material Design. So there's certain parallels that people are gonna see. They can tell it's a material design looking app. I'd like to give my app a unique visual color identity. So this is where things get a little bit tricky when it comes to React Native Paper and theming. So just over the course of working on this workshop, version five of React Native Paper was in progress in beta and then in release candidate. And it added support for Material Design 3, which is also called Material U. So if you're not used to the look and feel of the drawer here, that's new for Material Design 3. Now, the current state of things is with Material Design 3, which is what's used by default in React Native Paper, if you wanna customize colors, there's a lot of places you need to customize it. I mean, you need to customize this light purple, darker purples, you need to customize the different colors that show up in dark mode. You may not be able to, you probably can't tell, but this white text here is a tiny bit purple. This gray here is a tiny bit purple as well. So to customize the theme in Material Design 3, it takes a lot of configuration. In Material Design 2, which has been around for a lot longer, maybe since the start of React Native Paper, you can actually do it with one prop. You can set a theme color, a single theme color, and then all the different colors are extrapolated out of it. And so if you're willing to go back to Material Design 2, which you may be familiar with seeing, you can get a lot of theme customization with very little work needed. So for the sake of this demo, we're gonna do that. That way, you're gonna get to see a nice, different look and feel. And if you wanna go with Material Design 3, they're talking about whether they can add a single prop. I asked about it in our GitHub issue, or maybe in the Discord, and they're looking at the possibility of having a single color value to theme all of Material Design 3. But it's open-source maintainers, and they have limited time. So let's look into dropping back to Material Design 2, which still looks great, to get the ability to fully theme it very easily. All right, so what I'm gonna do is make a new file called the Used Custom Theme. We're gonna do this in two steps. First of all, I'm gonna set up the theme to use Material Design 2. And actually, when you have a custom theme, you have to handle light and dark mode yourself. So there's a little bit of work there. I'm gonna get that working with Material Design 2 as one step. And then in the second step, we're gonna add in the coloration. And after this, we may be close to a break point that might be good to take a little break, so we'll see. All right. So our default function, Use Custom Theme, in this hook, we're gonna first, say const color scheme, equals useColorScheme. So this is provided by React Native. And when you wanna ask, is it light mode or dark mode directly, you can use useColorScheme to get that information. And that custom hook will re-render and cause your components to re-render when that changes. I'm gonna default this to light. I forget if I saw that sometimes it returns null or for I was just being extra safe. But this way, at least we're sure, I think there may be delay as well. I don't remember. This is coming out of open source code that I created myself. But this way, we're sure that we always have a color scheme value. Next, we're gonna say, what's the base theme? And there's actually two different themes. Let me import these. In React Native Paper, it's md2 dark theme, and md2 light theme. Uh-oh. These are two different themes. When we're customizing the theme, we need to return one or the other of these depending on the situation we're in.

15. Customizing Theme and App Look

Short description:

We set up a custom theme using React Native Paper and Material Design 2. The theme includes a primary color that we specified. The app now has its own visual identity and a nice look and feel. We have implemented navigation that works on all three platforms and supports dark mode. The app skeleton is ready for further development and customization. We have achieved a lot with React Navigation and React Native Paper, which provide a high level of abstraction and allow us to target multiple platforms with the same code base.

I'm gonna say, what is the base theme? If the color scheme equals dark, let me use md2 dark theme. Otherwise, use the md2 light theme. And then for now, we're just gonna return the base theme. We're gonna modify this a bit later. We'll say, to do add custom theme color. But for now, we're just returning it. All right, so we need to use this custom theme. We can do this in APTJS. We could say, const theme. Use custom theme. Then we say in the paper provider the theme is... And again, this will re-render once we change from light to dark mode. So when we save this, this is gonna use our custom theme that's using material design too, coming from React Native Paper. We save and let's check out what we got. So in the simulator, this may be the material design you're used to, that you're familiar with. That super bright color at the top is purple by default in React Native Paper. When we open the sidebar, we have a purple tint to the navigation items here. And these look different because this is the look and feel for drawer items in material design too. Let's go back to Android and bring them back into the mix and take a look here. We have that purple material design top. We got the sidebar, it looks good. Our back button works as well. Looking good, you see that now that, in the theme now that there's a rich, deep color at the top, it's white text and links and stuff at the top. And on the web that looks like that didn't automatically reload. So let me reload that. Hmm, I got something wrong. Oh, is it maybe because dark mode? Let me search back to light mode. Yeah, so something interesting, and I was kind of surprised by this when I was first working on my app and using React Native paper with dark mode is, you get that vibrant color in the header in light mode, but in dark mode, it's gray. Instead, that's just part of the style. You don't like it, you can implement it or tweak it yourself. I wanted just a nice looking style out of the box. When I pull over the sidebar, we've got that purple looking feels on the web as well. And notice that we do have, if you haven't seen it, the nice animation, the ripple animation. And we click on any of the platforms. So we're on material design, too. We have a nice purple color and we do still have the purple in the sidebar there in dark mode, that's just the styling. So now we're ready to add a custom theme color. So let's do this. You can look this up, there's a link in the exercises there for to look up text codes. You may have tools look at past X codes as well. I'm gonna say const theme color equals, this is surely my to-do list app. The bright green color that I got. F4CAF50, you can fill in any color you want there. Emanuel asks, does it automatically pick up the theme of the system or does one need to code that as well? Emanuel, if you wanna clarify that question, you can. If that means light mode or dark mode, that is automatically picked up by React Native. If that means that your system, you've chosen colors for your system. I haven't looked into picking anything like that up in React Native or in React Native paper. So someone else might know more or the docs might know more, but I'm not aware of a way to pick up system theme colors, but it might be out there. All right, so for our theme, we want the theme of our specific app here, which I'm choosing as Shirley Green in this case. You can choose a color you like. So what we're gonna wanna do, oh, this is the wrong file. AppJS is not what I want, but I wanted to add in use custom theme because I want use custom theme to give me the colors that I want. All right, so we've got our base theme here. What I wanna do is what's our customized theme. We're gonna turn that. So I'm gonna spread out the base theme props, but what we're gonna override is colors. And here, we're gonna spread out the BaseTheme.Colors to get all the default colors there as well. But so far, this should be identical to what we had before as well. But then we say primary theme color, setting the primary color of our app to this theme color. And this is the thing that's different in Material Design 3. There's not yet a way to specify one property of one configuration object to change the color and to get all the colors of the app to go around, that's only available in Material Design 2 in React Native Paper right now. So let's save and let's see what we got. On the simulator, we've got green now, we've got surely green. And actually, React Native Paper sees that that's a brighter color and it gives us black instead of white for the text up at the top. You can see on the sidebar there, we have green for these items. And if we go to dark mode, let's see how it looks. The dark mode still doesn't use a color at the top cause that's default Material Design theming. But in the sidebar, we do still have the green. And you know, if you added buttons, well, we'll you'll see when we add buttons a bit later, those are styled to the color as well. So that theme color does still come out. On the web, we've got the color, check dark mode, looking good. And let's check in on Android as well. We got our color, so it was looking good. Our app has its own kind of visual identity, at least to my standards, someone who doesn't wanna style all the styles from scratch. All right, cool. So let's pause before we take a break and look at where we are. And we haven't added any app specific functionality. Of course, that's not the focus of this workshop, but we wanted to create a framework, an app skeleton for you to build on to make an app that looks and works awesome. And what we have so far is a really good place. We have an app, this is already a better, honestly, than any apps that I've written from scratch, other than using the set up. We have a nice look and feel, button is not styled yet, we'll do that a bit later, but we have navigation. Navigation that works on all three platforms. Remember that on the web, we're getting URLs as well, so that's good for bookmarkability and for browser back button and everything like that. It looks good, it's animated, it has material design, it supports dark mode as well, to save your eyes, which is really great. And so, yeah, we're in great shape. We've gotten a ton out of the box so far from React Navigation and from React Native Paper. It's a really, really great high level abstraction to build on and lets us target all three platforms with the same code base, so that's super exciting. So we're gonna take a five minute break in just a second. After that, we're gonna come back and talk about a few more things, responsive design.

16. Implementing Responsive Design

Short description:

We'll discuss responsive design, platform-specific functionality, and the pros and cons of building in React Native web. Then, we'll focus on implementing responsive design by creating a reusable centered column component. We'll use a view with specific styles to center the column within a wrapper. Finally, we'll apply the centered column component to all screens in the navigation and observe the results on the web and mobile.

After that, we're gonna come back and talk about a few more things, responsive design. In our web browser, I mean, even on my monitor, which is not that big, this can get very big, so how do we make this responsive and use the space a little bit better? A few different things we can do, including the Navigation Drawer. And I have some approaches that I've done and that help with some of the abstractions that are not available by default in React Native. The other thing that we're gonna talk through is platform specific functionality. So what do we do? Not everything is available on iOS, Android, and on the web, especially on the web. Browsers are locked down for a reason. And so how do we handle functionality in our, if we have one code base here, how do we handle situations where things are not available on the web? Or maybe we just want things to look or feel differently on the web or on mobile. So we'll handle that as well. And we'll take a look through my Shirley code base for some examples.

Finally, what we're gonna do is wrap up and start talking about the pros and cons. Like once we've gotten a taste of actually building in React Native web together, we'll talk about when would you use this for a real project, and when would you not? Clearly people still use React on the web instead of React Native web for all cases. So when should they, when shouldn't they? And I tend to not be very prescriptive, but I'll share my thoughts on the trade-offs and pros and cons. And if any of you all want to share your thoughts as you go through, be glad to have that as well.

Let's get started with our second portion of our workshop and our next focus is responsive design. So just in the last few minutes, I added some repeating text here to show that the text goes all the way across the window. And that's very, very wide. And that's probably too wide. That's probably not very useful. So what we'd like to do is to apply some responsive design here. And I'm a very basic designer. I have only very basic knowledge and ideas. And so the idea of a centered column is what comes to mind for me. I want my content to be centered in the window so that I can see it and so it's not so wide and it's unwieldy and hard to work with. So let's look at how we can do that. We can create a centered column component that's reusable in multiple places.

Let me pull instructions back up. Yeah. Center, column, and styling this is actually pretty straightforward. So, export default, Oh, sorry. I'm getting sent back and forth between different apps. What is going on here? I'm gonna type in the meeting chat. Oh, well, function center column. We're gonna take in column style. And again, I'm not gonna use this directly now, but just for the sake of easier style ability. We can take in children. So we're definitely gonna wanna be able to pass children into our columns here, and we return. What we're gonna return is a view. Style equals styles column. Let me define the styles down below before we put it in place. So if you haven't used React Native before, this is how we create reusable style sheets. There's a style sheet API. You call it stylesheet.create, and it happens at the top level of a module, and you can create styles. And you use a JavaScript-based API here where you can create different styles you can apply. So we'll call one column wrapper, and we'll call the other one column. So the column itself, and then a wrapper around it as well. So what we're gonna do is basically set a column in the middle that's gonna be a fixed width, and then the wrapper goes further out, and we specify it so that the column is centered within the column wrapper. So we're gonna have a 640 pixel wide column centered. And so now we need to implement that. So we use a view here. The outer view is styles.columnWrapper, and that's how we reference that style. And then inside it we have a view style equals styles.col, and we also allow the column style that's passed in there. Children. So these two nested views is what's gonna get us that centering functionality. So let's take a look. Oh, we haven't used it anywhere yet. That's right. We gotta use the center column. So let's center all the screens in navigation. Incidentally, usually in my app setup, I wouldn't have the whole contents of all of the screens right inside my navigation file as well, but I do this just for the sake of ease of finding things, because these screens are so small. This kind of puts it all in one place, just for the sake of demoing here. As usual with React, you can extract things out in a separate files whenever you find that it's useful to do so. So I'm gonna put this center column here, and I'm gonna put it inside the screen background. That way, the light and dark mode background extends all the way to the outside, and it's just the contents that are centered. As I've said several times, if you find that you're duplicating this a lot through your code base, you can create your own abstraction to put it in one place. Let's save and see what we got. All right, our web page reloaded, and we've got a centered column now, and that text wraps with margin on the left-hand side and the right-hand side. And if we use, you can shrink the window. We can see that it's staying centered. And if we get narrower, we see that the content just fills the whole area. That's why we use the max width there, so that it's like, oh yeah, it's totally fine for the column to be narrower as necessary, but we just max it out at 640 pixels. Let's see how this works on mobile. Our mobile app, I'm gonna switch back to light. Well, the dark. Yeah, I'm gonna switch back to light mode just for the sake of parallel here, so we're not distracted by the styling difference. It looks like that didn't reload to get our new content, so let's reload that. Oh, it's the home detail that I put that in. Okay, we go to the detail. That's all wrapping just fine.

17. Responsive Design and Device Compatibility

Short description:

The responsive design works well on both mobile and web. The app adjusts its layout based on the screen size, ensuring that the content is displayed correctly. Whether it's in light or dark mode, the app adapts to provide an optimal user experience. The versatility of the app allows users to access it on various devices, including tablets and smartphones.

And if we use, you can shrink the window. We can see that it's staying centered. And if we get narrower, we see that the content just fills the whole area. That's why we use the max width there, so that it's like, oh yeah, it's totally fine for the column to be narrower as necessary, but we just max it out at 640 pixels. Let's see how this works on mobile. Our mobile app, I'm gonna switch back to light. Well, the dark. Yeah, I'm gonna switch back to light mode just for the sake of parallel here, so we're not distracted by the styling difference. It looks like that didn't reload to get our new content, so let's reload that. Oh, it's the home detail that I put that in. Okay, we go to the detail. That's all wrapping just fine. It's not extending too wide or anything like that. Same here as well. We'll just go in full width. Now let's, to make sure that the dark mode background extends all the way out, let's switch to dark mode in the browser here. And yes, our dark mode setting extends all the way to the full edge of the screen, so that looks good. Incidentally, I'm not gonna demo the app in iPad Simulator or on an Android tablet, but once we've handled responsive design, we're coding just the size of the viewport, and so our app doesn't care if it's web or tablet or what. So once we have responsive design working, it's gonna look great on all screen sizes, on web and on mobile. Incidentally, the app pulls up just fine on mobile, on the web as well. Let me just show you that. Just so you can see how versatile this is. In a mobile web browser, we can go to, that's my personal website, we can go to that local host URL and the app is there, it looks good, it's not animating like just the web browser, but everything still looks good. So people on mobile can use your mobile native app, or they can use your mobile web app. All works great.

18. Responsive Design with React Native

Short description:

To achieve responsive design in React Native, we can use media queries and breakpoints. However, React Native does not include media queries by default. There are various styling libraries available for React Native, some of which include responsive design features. If you prefer a low-level approach, you can create your own responsive design logic. I have created a small library called react-native-style-queries that provides a good abstraction for responsive design. In this section, I will show you how to use it, but you are not limited to my library. You can use any other library or custom code. Let's add the react-native-style-queries library and create a file called breakpoints to define our breakpoints.

All right, so that was a very basic need for responsive design to get a centered column. Let's look for some more advanced needs as well. So something that I like and that I use for my app is the idea of buttons. So it's very typical when you've got like a form you're editing to put buttons left and right, like next to each other horizontally. But on mobile, it's more typical for them to be above one another because screens, especially in portrait mode, screens are narrower. So what we wanna do is to have buttons that are one above each other on a smaller screen and next to each other on a larger screen.

So to do this, things are a bit more complicated. Now, if you've done responsive design on the web, you might be used to media queries and the idea of breakpoints. So you can say, hey, if the screen width is smaller than this or larger than this, apply these styles conditionally. Now, media queries are a CSS feature and they're not included by default in React Native's styling approach because it's not CSS. It's just CSS inspired. There are a lot of different libraries for styling you might use in React Native. And, you know, a lot of them that are kinda medium-sized, like they're, unlike, you know React Native Paper is a very high level of abstraction that gives you all these components ready to go out of the box. If you're using a library that lets you build your own styles, but with adding some more features, probably it has responsive design built in. I like the option to be able to go very low-level at that. And so I actually created a very small, very low adoption library that allows us to do responsive design with React Native, and it creates what I think is a good abstraction. So I'm gonna show you how to use that. You can custom code this yourself by getting the React Native screen size and adding conditionals in, but I found that tedious and frustrating, and I wanted a nice abstraction like media queries that I could work off of. So let me show you that, and just know you're not locked into my personal library for responsive design. You might have another library, or you might be able to code it yourself as well. If I can code it, you can definitely code it, that's for sure. All right, so let's quit outta here, and we're gonna add the library. So my library's called react-native-style-queries. It's like media queries, but it's queries. It's conditionals for your styling in React Native. So it's React Native-style-queries. All right, so the next thing we're gonna do is create a file called breakpoints. Right now we're only gonna need a little bit of information, but we're gonna be more as we code more. breakpoints.js. Right now all we need is the value, the medium breakpoint. Eventually we're gonna have small, medium, and large sizes, but right now breakpoint medium is all we need. So let's add that in.

19. Implementing Responsive Design with Button Group

Short description:

I'm gonna create another reusable component called button-group. We'll use React Native's Flexbox implementation to implement responsive design. With React Native Style Queries library, we'll define styles based on screen sizes. We'll use the useStyleQueries hook to apply the styles conditionally. We'll put the button group into use and surround it with React Native Paper buttons. We'll test the app on mobile, Android, and web to observe the responsive design.

I've definitely found, you know, you don't want these sizes to drift and get out of sync all the way through your application, and so when you're styling off of breakpoints, you probably want to centralize that logic in one place. So now I'm gonna create another reusable component. I'm gonna call it button-group. It's the idea of anytime you have several buttons together, I want this responsive design functionality. So let's code that.

Button-group, children. We're gonna allow those buttons to be passed in as children. So let's just start out with a basic view around it. Children. And now we need to decide how are we gonna implement that responsive design functionality? The way we can do this is with React Native's Flexbox implementation. If you've used Flexbox on the web, you know, and even from what we just saw, there's a flex direction. It lets you say, is it in columns or is it in rows? And I think that's exactly the property we want to change responsively. Are we going with organized things in columns for smaller screen sizes or organizing things in rows for larger screen sizes? So let's work on that.

With React Native Style Queries library, I like to conventionally, just like usually with React Native Styles, you create a styles object at the root level. I like to create a style queries object at the root level. And like with Styles, you have named concepts here. So you say button container. You want to style this button container. The difference with style queries is instead of one object assigned to that name, you have an array of multiple config objects. And here's how they work. First of all, if you have just an object that's directly under that array, it's applied unconditionally. So these are our unconditional styles, our base styles. And with mobile first design, it's usually a good idea to start with the smallest screen size Styles first. So what's the defaults? The default we want for on mobile is flex, direction, column. So on small screen sizes, we're gonna have columns. And now we say, okay, now we want to reverse the direction when it's larger. When the screen size is at least so big, we want to change the conditions. And so there's a data structure you can use for this, but React Native Style Queries provides some helper functions that make it just a little bit more readable. And so I'll import one of those screen width min, comes from React Native Style Queries. Here where you can say is okay, what is the minimum screen size? And in this case, we want to use the break point medium. So we're saying here is basically always apply these styles, but then if the screen width is at least break point medium, apply these styles on top, potentially overriding the base styles. And what we're gonna override is we say flex direction is row and then also, we wanna justify content to flex end. That in a default left to right language, I shouldn't say shouldn't say default. In my default, which is left to right languages, flex end is gonna align things to the right. So if you're looking at the screen, it's on the right hand side. And that's very typical since early Macintosh days, 1984, the action buttons are aligned to the right, and so that's gonna look good. So again, what we're saying here, and this is the API that React Native Style Queries provides a declarative way to say, here's some unconditional styles, here's some conditional styles to apply on top of it, if the screen width is at least this width. So now how do we use these and put these into practice? We have a styles object in here, and we say use style queries that comes from React Native style queries as well. You pass in the style queries configuration, and you get styles back. Styles is a normal React Native styles type of object structure where you can just say, view style equals styles button container. You can see, you can think of it like flattening. Style queries has these arrays with this conditional, you know, multi-logic that might have conditions. Use style queries takes that in, it runs, it's a hook, so it runs in the context of the component, so it has access to things like what is the current screen width and other properties like that. And it flattens these down into like, what is the one set of styles for button container that's then ready to be applied on the view there. So this is gonna cause our app to re-render as the screen size changes or browser size changes, it's gonna change these styles and apply them conditionally, depending on where we're at. So we have our button group now, let's see it in progress, and then I think that'll help you to visualize it, but we do need to put the button group into use first. So let's go into home root there. And I think what we're gonna do, we've been using this very basic pressable now, but now that we have React Native Paper, let's go ahead and use a React Native Paper button as well. So we're gonna remove this, we're gonna put the button group around it first as that wrapping container and then we're gonna take in a React Native Paper button. So we're gonna call it button. Let's look at the properties here, there's a mode outline that makes this first button outlined and we're just gonna say second, you have a second and a third button there just to have three of them, we're not gonna have them do anything, we just need some buttons to visualize this. And then for this last one, we'll say mode contained, kind of like it's the primary button. We're gonna give that one the on press where we say navigation, navigate, home detail is what we were doing before, go to detail, save to get that format in. So now we have three buttons in here but we've surrounded it by the button group that we're hoping will give us responsive design. So let's take a look first in mobile. Q&O says grid instead of flexbox, what do you think? So I'm not actually sure if React Native has CSS grid, let's take a look and see, let's take a little side track on that, because remember what's available in React Native is not CSS. So nothing by default comes over from CSS unless React Native has implemented it. That's one of the interesting implications and I'm gonna come back to that in our summary. When we're building a web app through React Native Web, we're generally not using CSS directly, we're using React Native Styling and React Native Web will turn that into styling for the web. So if you were to use CSS grid, there might be a way to get that working and React Native Web, but then it would not work on mobile. But let's see if that's available. When I search for grid in the reactnative.dev, I don't see any results. And so let's take a look at guides. This is where you'd wanna go if you're building in React Native, including React Native Web to find out what's available. Design, style. So here's where a style is. We have layout with Flexbox. And again, I don't see references to CSS grid or anything based on that. I'm sure there's open source React Native styling libraries that have grid functionality, but I just haven't looked to use them before. So yeah, this is a very important implication of using React Native Web is that you do not have CSS available to you. You need to approach things in a different way. Cool, that's a great question. Thank you for that. All right, so let's take a look at the mobile app. Again, oh, that's web there. Let's look at the mobile app app. It's disconnected from Metro. Did I restart the server? I did not. Let's start the server back up. I'm gonna reload here. It loads up. And then on mobile here, there's the buttons one above each other. They don't have any spacing between them. We'll come back to that in just a second. I wanted to set up the basics to start. Let's check on Android as well to make sure how that looks. Go back, reload. Loads up and the buttons are one above each other for these small screens. So let's check on web. On web.

20. Implementing Responsive Design

Short description:

The app responsively adjusts its layout based on the screen size. On smaller viewports, the buttons are stacked vertically, while on larger viewports, they are aligned horizontally. The app supports responsive design by applying conditional styles based on the screen width. The buttons have a margin on larger screens to create space between them, while on smaller screens, the margin is removed to maintain a balanced layout. This approach allows for natural and intuitive button styling on different screen sizes, making it suitable for both mobile and tablet apps.

Again, I think because I killed the Metro server, it did not reload automatically so I can reload now. Oh yeah, I gotta press W to start out Webpack when I restart Expo. So I press W, that's restarting. We reload here. And now the buttons are next to each other, aligned to the right. Remember that this is the size of the center column there. So we're getting our responsive design on a smaller view port. They're above each other. On a larger view port, they're left and right. And let's check this out by growing and shrinking the window. You may find, oh, that actually allows us to shrink. If you have the penny on your browser, it may restrict you and you may not be able to go narrow enough. It looks like mine does. But something that can be helpful when you wanna be able to go really narrow, I like to put the browser developer tools to the right-hand side. And that way, I don't have to shrink the window. I can just grow and shrink those to see. So you can see that our app responsively, when it gets wide enough, the columns turns into rows and the buttons are aligned and they're aligned to right as well. Now if that doesn't look great, it'll be nice to have some margin as well. So let's add some styling there because that shows a bit more nontrivial layout options. Let's add this in. Again, this Navigation.js file is getting pretty big. But let's add it in here just for the sake of getting it working. We're going to find some style queries as well. We're going to style buttons here. We're going to give it the array because we have our multiple styles to apply in different conditions. By default, I want a margin of top of 10 because that's going to keep this off of that text right there and give us a little spacing. In general, I just want some space above those buttons. And actually, that way in Column mode, there's going to be a space above each of the buttons. So either way, I do want that spacing on the top. But then let's add a condition. Again, screen width min, breakpoint medium. And if you're doing mobile-first design where your small screen size is the default, screen width min is what you're going to most typically use because you say, only when we get bigger than this size should we apply these conditional styles. So what I'm going to say is, for larger screen sizes, I want margin on the left so there's space in between these buttons. I don't want that on smaller screens, though, because I don't want a margin on the left here. That would look strange. I want it to be equal on the left and right. So we're going to say for larger screens, margin-left of 10. Now we need to apply these styles to the buttons. So I'm going to pull these in here, const styles equals use style queries, style queries. Now from these styles, we're going to say style equals styles-button, button. Now we save and let's see what we got. So yeah, we now have a space in between these buttons, so that looks a bit better. On a small screen, we have space above it. Now notice the buttons do still go to the very edge of the screen. That wasn't something that I wanted to get into, you know, adding padding around something is not too hard. That's pretty easy. But where you put it in your app, depends on what you're doing and whether you're using flat lists and things like that. So that's all pretty typical React Native styling. When I wanted to show you, this is actually the first time I did a lot of styling for React Native on my app, What I wanted to show was the responsive design of having this margin here show conditionally, only when you're on a larger screen. And so when we get down to a small screen, it just flops around and really any style attributes you wanna change, you can put them in conditional based on the width of the screen, based on responsive design. So we've got some nice buttons that look very natural on smaller screens and on bigger screen sizes. And again, that would work just great for iPad apps and tablet apps as well.

21. Implementing Responsive Behavior for the Drawer

Short description:

We implement responsive behavior for the drawer based on screen size. On small screens, the drawer collapses and is not shown, while on larger screens, it is always visible. We use the use breakpoint hook to determine the current screen size and configure the drawer type accordingly. The drawer can be either a permanent drawer or a back drawer, depending on the screen size. We test the implementation on web and mobile, ensuring that the drawer behavior is consistent across different screen sizes.

Also, when you have a split screen in your tablet, if you have a small app on the side, like I know it works on the iPad, it'll scrunch down to a smaller screen size and work like it works in the iPhone. It'll all work out well.

All right, so another responsive feature, it's kind of different, but we wanna uncover it, relates to the drawer. So on small screen, on mobile, it's nice that the drawer collapses and is not shown. On a bigger screen though, imagine this window goes all the way across. We have all this space on the left and the right. It's kind of tedious to have the drawer collapse. It will be nice if we took advantage of that screen space to just always show the drawer on a larger screen size. And that's something we can handle. We have access in React Native to the screen width and React Navigation has a property that lets you say whether the drawer is persistently visible or whether it's toggled. So let's look how to implement that to get the drawer toggling. This is something actually, there's been some bugs over the course of a couple years I've had these apps running where issues were more found here but folks maintaining React Navigation did a great job. Some of us in the community collaborated and found, I don't know if I helped but they helped and found a solution, a workaround. And they've fixed bugs since then in React Navigation to get it working. So I'm so thankful for all these collaborators in the open source world to help us to be able to make a cool app like this.

All right, so let's get this implemented. We're gonna need to implement more in the breakpoints file. So I'm gonna copy and paste this over here and then kind of talk through it. So what I've added in now is two different breakpoint values, medium and large, 429 pixels and 600 pixels. Again, device independent pixels. So this is what's gonna allow, tell us about when we go from small to medium and medium to large. We don't need a number for small because the starting point of small is zero pixels. If there is a screen, if there is a window, it is small unless it's 429 or unless it's 600. So there's these different breakpoints. I also gave names to them, small, medium and large. These are just strings so that we don't have to hard code those strings so at the app at risk typos, it's nice to be able to have constant values for that. Then I've added a hook, use breakpoint. And what this is doing, it's using the use window dimensions hook that comes from react native to allow us to get the current width of the screen. And then I conditionally return the name of the breakpoint based on the breakpoint that we're in. What this is kind of creates a little bit of an abstraction so that I don't need to use window dimensions and do comparisons all throughout the app. I can just use this custom hook, use breakpoint to get the name of the current breakpoint that I'm on. If that's helpful for me for coding a logic off of it. So because in this case, we got conditional styles when it's react native style configurations with react native style queries. In this case, we don't want styles. We need a value that we're gonna pass into react navigation. So we can't use reacting with style queries. We need the values ourselves to be able to code logic off of it. One of my favorite things about react hooks is the fact that it's so easy to create custom hooks like this to create a simple abstraction. So we don't need to repeat this conditional logical throughout the app. I can wrap use window dimensions with use breakpoint. And now I have a very nice usable hook I can use all throughout the app. Really, really love that. All right, so with this new breakpoint logic, we can see how to configure the drawer to be conditionally present all the time. So let's go down to our drawer navigator. Where is it? There it is, our drawer navigator. Actually, it specifically has navigation contents. So we're gonna get the breakpoint, equals use breakpoint. So it's gonna give us the current breakpoint value. Then I'm gonna define a constant here, drawer type. I have trouble saying the word drawer. Breakpoint, I'm gonna test. If breakpoint is equal to large, and I'm importing large, that constant from breakpoint is there. So if we're on a large screen, permanent, we use a permanent drawer, otherwise, what's it called? A back drawer. There's actually, it's not just permanent or not. There's like several different types of drawer style. Like sometimes it overlaps the screen, sometimes it pushes the screen over. And so there's some differences there between the different platforms. And this was related to the bug we found. We found in the community that, when you were toggling back and forth between a drawer that was permanent, sometimes, the back option was the better other option to use. It avoided some issues where things got weird or stuck, or got pushed over twice the amount, or something like that. That's all implementation details as far as like, oh, what configurations are gonna work here? But we've found that this configuration at one point in time worked great, and it still does. So we have a drawer type configuration now, and all we need to do is pass it to the Drawer Navigator, Drawer type, and we're using that ECMAScript shorthand where now the Drawer Type key is passed in, and it's the value of that variable that's passed in as a value. So let's save and see how it works. Let's look at the web first, because it's easy to get it nice, wide in size. So we see here, and I'll reload the screen just so you can see it. From the start, we have the drawer always visible. Even when we're moving around, going to the detail screen, the drawer is persistently visible and making use of that space. So that works out really well. Now let's see what happens when we shrink the window down. When we shrink it to small enough, and that's a configurable value, the drawer disappears, and now it's toggle. Now we can toggle it in at smaller widths. But if we get wide enough, it becomes persistently available. Then actually, even if we're toggling when it's toggled out, it shows up fine. It goes back and forth between being permanent and being toggled open. We can toggle it back. Let's take a look on mobile, as far as a smaller screen. I'm going to, I think it automatically reloaded, but let me reload just to make sure, so you know that when we're getting the latest code. So on this small screen, it toggles it from the side just fine. And let's make sure we're good on Android as well. Small screen toggles out from the side. So we're good. Cool. So this was really exciting to me, because this gets us from the point where it's like, oh, you know, beforehand, when the sidebar is already toggled, it looked awkward. It looked like, oh yeah, you've taken a mobile app and you've scaled it up for a web browser for a larger screen. The same thing would happen on a large tablet. But now it looks intentional, it looks like on a large screen, oh yeah, you just plan to have a left-hand sidebar there. And on a small screen, oh, you just plan to have a collapsible. And in fact, we can switch back and forth and get nice dynamic behavior on the web. The same thing happens, depending on the screen size, if you're on a tablet where it changes, in portrait mode, you might have a toggleable sidebar and on landscape mode, it may be permanently there. But whatever your sizes are, you're gonna get the right behavior for that screen size.

22. Implementing Toggle Button and iPad Simulation

Short description:

We can conditionally hide the toggle button on larger screen sizes. The custom navigation bar logic is used to determine whether to show the toggle button based on the screen size. The break point is set to 'large' to hide the button. The break point logic ensures that the toggle button is shown on smaller screen sizes and hidden on larger screen sizes. The code is wrapped in a conditional rendering based on the 'show drawer toggle' value. The drawer toggle button is only rendered if the value is true. The iPad simulation is available in the Expo Go app. The speaker's live streams are available on Twitch and YouTube, covering topics such as React Native Web, Expo, and testing. The speaker's website, codingatlong.com, provides additional ways to stay in touch.

Works out really great. There's one other thing on the toggleable sidebar that I wanna do though. That is related to this menu icon. So when the sidebar is permanently shown, this doesn't do anything. It's just always shown, it doesn't function. And so not only, I mean, I don't need it to do anything, I don't even really want it there. It's kind of confusing to have a UI element that's not needed. So we can conditionally hide this on a larger screen size. So let's take a look at how to do that. We're gonna go in our custom navigation bar and we're gonna pull in the same logic using the hook. Const breakpoint equals use breakpoint. Oh, it's interesting. It's not automatically importing. I wonder why that is. Language server, not always perfect. Import. Breakpoint. So we've got our used breakpoint hook there, and then we're gonna again, define a custom value, show drawer toggle. Do we want to show the toggle button? Well, if breakpoint is not equal to large, we wanna show the toggle button. So smaller sizes show the button. Once we're at large, though, don't show the button. That's what that conditional is gonna give us. We're gonna take this, and we're basically gonna just wrap this action button in the conditional. So we say show drawer toggle. If so, show the action button. And if not, we're gonna get a false there. It's just gonna render it nothing.

Jan says, is an iPad simulation available to test that? It is. Oh, and I saw I missed another question, so let me back up. Viki says, flex gap not available too. I don't know, I do remember wanting and missing flex gap. Yeah, it looks like in React Native Flexbox, I don't see a flex gap property, unfortunately. So you might need to do similar workarounds to the what we did on the web before flex gap was available. All right, Jan asked, is an iPad simulation available to test that? Yes, we should. I've not done this on my app. I don't know if I've done it ever, but we're gonna do it live on the call, cause we have time. So yeah, let's save this and see this working, and then we'll test it out, we'll find an iPad that has a size, cause they boot up pretty quickly in the simulator. So yeah, let's come back to that in just a second. This will be fun, a fun experiment. I like to be put on the spot, and I like it when things go wrong, people that watch my live streams do as well.

Alright, so let's take a look here, custom navigation bar. We save, we see on this large screen size, the drawer is permanently available, and the toggle button is not shown. Let's shrink down. Now the drawer is conditionally shown, it's toggle-able, and the toggle button is there. We can toggle it. And as soon when we watch this, when we see it, let's look at the point. As soon as we cross over that pixel point, as soon as the drawer is shown, the toggle button goes away. And as soon as it disappears, the toggle button shows. That's one of the reasons to put your break point logic and the sizes in one place in the code base, that way those don't get mismatched, and you don't experiment. Oh, let me see what the width needs to be, and you hard cut another value there, and they get out of sync. You wouldn't want to get to the point where the drawer was hidden, but the toggle wasn't yet shown, you want it to cross over, that's two conditions. You want to code to that specific break point, and so using this code this way really helps with that.

Dimitri says, you have live streams, I'd be interested to watch, is it on YouTube? Thank you. Yes, so I'm pausing on my live streams at the moment, but there are recordings. Those are available, they're linked on the conference webpage. Sorry, the workshop webpage, they're linked from there. I'll show you real quick on here, if you go to Coding at Live, Coding at Live is the name of the website, the links to my streams. It is on Twitch. I'll update it right after this and say they're on pause for right now, but the past recordings are all available. And so, on a lot of these streams, I actually built out, I've been talking about Shirley as a React Native Web application for web and mobile. I actually built out a second application using the same approach called Firehose. It's a link saving application. And so, if you want to walk through a process of seeing an app being built using React Native Web and Expo from scratch, those are available on my YouTube channel there. So yeah, if you go to Coding at.Live, you can see some more there. I also like to talk about testing a lot, and so React Native testing is another topic I hit upon a lot. And so, you can stay in touch with me there, as well as on codingatlong.com is where my social media, blog posts, and other ways to stay in touch with me. So cool.

All right. It is now time to be challenged and to do something live I haven't tested before. And we're going to try out an iPad in the simulator here to see if things work the way... I've so confidently told you that things work great on the iPad and you asked to see it. So let's see it. Let's take a look here. Let's try iPad 10th generation to start. And as iPads have changed, I'm not rich, and so I do not have all the iPads, like some of you might. And so I haven't seen exactly what the break points are for different iPad sizes to see how these break points will work out. I have thought about. If I had any customers for this Surely app, I probably would have bought an iPad to be able to test the experience for them. So I've opened this and let's close this. I forget how exactly Expo tells what to open on the simulator. But I think if I have one simulator open and I press I here, I think it's gonna load it up. So let's do that. Let's see if it works. Opening on iOS. Yeah, opening on iPad 10th generation. Dresses a minor note about Expo. You see here that it says downloading the Expo Go app. The way that Expo works by default, and there's other options as well, is that you just write the JavaScript code and they have a pre-built mobile application, React native application that has all the native code. Expo actually allows you to develop. Even if you don't have a Mac, you can develop apps that run on the Mac because you don't need the simulator.

23. Using Expo's Pre-built iOS App on iPad

Short description:

You can have Expo's pre-built iOS application and open it on the iPad. The app opens fine and the sidebar is permanently visible on the screen. The sidebar width is adjusted based on the screen size, ensuring a good layout. The app looks good on the iPad.

You can just have Expo's pre-built iOS application, which is nice. We're gonna open up our app on the iPad. I kinda hope there is a bug because that would be fun because I like to be embarrassed and also it'd be something fun to work through. Our app has opened up just fine and we see that on this screen size, these are draggable to see, so I don't actually know how big physically an iPad 10th generation is but we can see pixel size wide that it's decided that even a portrait mode on this iPad, it's wide enough that you can have the sidebar permanently there. Certainly if we rotate the iPad, that's wide enough. We can see that there's space for the columns there on left and right. This is interesting, actually. Based on the max width approach that I took, on this screen size where the sidebar is permanently there and it's pretty wide, honestly. In my, in Shirley, I think I shrunk the size of the sidebar because like, I mean, this text is very narrow, then sidebar doesn't need to be that wide. But so here, we're less than that 600 pixel, 640 pixel max width there. So we don't have a gutter on the left and right hand side but that actually works out pretty well. This looks good on the size iPad.

24. Testing and Responsive Design

Short description:

Expo allows you to deploy and test your app without publishing it in the App Store. It is a recommended tool for React Native and React Native Web development. The sidebar can be collapsed on different devices, and safe area issues can be handled using React Native's code approaches. Testing is essential to ensure a good user experience on different platforms. React Native elements is another UI component library that can be used for specific components.

Vicky says, what's also nice with Expo, you can kind of deploy and give your future users to try the app out without even publishing in the App Store. That is a really great thing about the Expo flow as well. I agree, Vicky. It was a lot of fun.

Okay, so this iPad, I want to find an iPad that in portrait mode, we actually collapse down the sidebar. So let's experiment some more and see if we can find one. There's just so many of them. iPad Air maybe, let's try iPad mini 6th generation. If it gets small enough, it might actually be collapsible sidebar on all the sizes. So let's try this and find out. Yeah, with Expo, basically, because you can download the Expo Go app from the App Store, people can just download that and you don't need to set them up as testers that you sent them a built iOS application. So that makes that a little bit easier. I don't know if I'm summarizing it well. Vicky might be able to summarize better, but yeah, Expo is a great tool. If you haven't built on React Native yet, definitely check it out. And again, if you want React Native Web, Expo is the recommended way to do it.

Alright, well, so it looks like on the iPad mini in this case, even on this size, it's collapsing. It's showing the sidebar permanently. Let me let me tweak the values here so we can see when it collapses down and that might be enough to show. Luckily, I got embarrassed, that's good, not actually embarrassed. If we change the breakpoint large size. And there's probably, I'm sure there's websites where you can see screen sizes of different Apple devices. Let's say 700. That's not big enough, 800. There we go, okay. So when I set the breakpoint large to 800, this shows us in our iPad mini in portrait mode, we are actually able to toggle the sidebar. So we toggle it out. Let's see what happens when we rotate. When we rotate, we actually get the sidebar popping out and it's consistently available there and we no longer have the toggle. So that's pretty cool. And let's even try when we have it manually toggled out. We rotate, it's there unconditionally. Let's see if we can show you when we rotate, it's there unconditionally we rotate there, now it's there conditionally. So this feels cool. I mean, this feels like a real mobile app with a lot of a rich functionality and nice looking feel. Yeah, I just like this responsive design. I think, you know what it was, I think 600, actually one of the things I tried to think about when I was thinking about the sizing for my app was, I think for some of the really large phones, they're actually large enough so that in portrait, in landscape mode, the sidebar is unconditionally shown. You might or might not want that, so you might need to toggle your responsive settings to really fit. But let's try the iPhone 14 Pro Max, let's just get the largest resolution. I don't keep up with Apple news, so I don't know exactly about the sizes, why is there a Pro? Why is there a Pro Max? I'm not actually sure. And it seemed like when I was testing, the sizes were somewhat similar. But let's see what happens with the Pro Max. If you are building for iPhone, one of the nice things about having a Mac is that you can run all these simulators locally and try all these things. But there's hosted tools that give you options as well. So on the Pro Max, it's still, no matter how huge this phone is, it's still small enough that our sidebar is toggleable there. Let's rotate it and let's see. Oh, actually there's a setting. So yeah, there is a, this is fun to experiment together. So in Expo, there's a setting here that lets you change the portrait. So right now the app is fixed to only work in portrait mode on mobile. On iPad, clearly you can rotate it anywhere. Let's check, we have time. Cause we're not in a rush. Let's check the Expo docs here and let's find the setting to allow it to rotate. This is all very on target cause we're not tight for time for three hours. Orientation. No, I want it, I want config, I want app.json. There we go. Properties. Orientation, default, portrait, and landscape. Logs your app to a specific orientation with portrait and landscape, valid values is default. Okay, so we want orientation default. So let's try that. I'm gonna reload to make sure and now let's see if we can rotate. Remember, this is iPhone Pro Max which should be hopefully a pretty big phone. Yeah, so check that out. So on, oh, there was a little bit of visual issue there, I think. I mean, probably you can rotate it fast enough. Yeah, there we go. So I rotated it fast enough there was a bit of a timing issue. So that'd probably be good to debug. But yeah, on a iPhone Pro Max full-size, sorry, a phone is just one size. On an iPhone 14 Pro Max, with my breakpoints the way I have it set up, landscape mode is wide enough that the sidebar permanently shows. And now you see I have some safe area issues here where the drawer here automatically handles the safe area. So if you rotate in this direction, your navigation items don't overlap on this floating notch, whatever it's called. And this orientation of the phone works fine, but if I rotated this direction, this button is all the way over here. So this content would overlap this notch. So React Native has good safe area code approaches. And so, there's components you could put in there that would keep this part of your screen safe there. This is one of the reasons that if, you know, there is, if you're targeting all the iPhone devices, all the Android devices, and all web devices, like there's a lot of things to cover. Like you're gonna need to test out, I mean, test on web on iPhone 14 Pro Max as well, and make sure that it doesn't go into this, that your content stays in a safe area as well. So, you know, this React Native web doesn't solve the work that's needed to, all the work that's needed to target all these different platforms. You wanna test to make sure things are good. What it does, it allows you not to have to build from scratch, and allows you not to have to learn three different ways to identify safe areas. You can use React Native's abstraction for safe areas, and your app is gonna be able to cover them in all these cases.

Chad says, have you ever used some other a UI component libraries, Vicki says, maybe for some specific components you can recommend. View the slide up from the bottom. I'm not sure if paper has it. I'm not sure if it has that as well. I remember another, the component library that I use is React Native elements.

25. Platform Specific Functionality and Conditionals

Short description:

React Native Web allows you to have an awesome website and mobile sites. You can add conditionals to display different functionality based on the platform. The website and mobile app are both great and both work really well. This is one approach to different platform specific functionality.

That's another one that's been around for a long time, has a lot of really basic, useful components. It's not based on any particular style, like React, like material design. And I think it can tend to be closer in some cases to what's default on iOS. At least for me as an iOS user, it feels closer like list views and things like that. I don't know if it fits what's natural for Android. It might, or it might not. It might have different components that are more natural for iOS or for Android. And I know that I've heard really good things about React Native elements for years. I'm sure there's others. There's others even some of them that are lower level things. Like I said, I know I've heard some of the folks that have been on my live streams have talked about different design libraries. Unfortunately, I don't have too many recommendations myself but if you get into the chat here at the conference or other React Native communities online, folks will have recommendations on that. So cool, that was some fun experimentation on this responsive design here. And I was able to prove out thankfully, yes, that this responsive design does in fact work on iPads. I don't have an Android tablet so I don't have that up in the emulator. So I'm not sure if that will work but it sure seems like it will. And if there's a bug, I'm sure you can work around it. All right, that was a great rabbit trail and in responsive design, but remember where we're at. Where we're at is we now have this nice permanent sidebar that stays out if we have a large screen size. Surely my to-do list I use all day every day. I literally live out of my to-do list because that's just the way I'm wired. And so I've got it up in a web browser with my sidebar permanent and I've got it on my phone where I pull up. And so I use this every day. Carola says, do we need to look at some kind of specific compatibility notes of libs to work on mobile and web? Yes, you do, that's a great question. So, I mean, I haven't tested extensively and then clearly the Ease React native web apps that I've made are pretty basic in functionality, but you will wanna see in the README of these libraries, does it work on a web? And certainly if you're looking to make a React native web project, you're gonna wanna say from the start, well, what are the essentials? If I have a map-based application, then before I do anything else, I wanna get the map running on web and on mobile to make sure that it's gonna work great before I build everything out. Now when we get to the, which I think is coming right after this, actually, we talk about platform specific functionality, even in a worst-case scenario, say you have a library and you're like, this just doesn't work on web, it only works on mobile. You may need to implement yourself on web or you may need to find an alternative on the web. Maybe you can contribute to the React native library to give it better web support, that could be cool. But not everybody has the capacity for that, I have not done that before. So what you can do in your app is have conditional code where for the web, you have conditionals around it and you say on the web load this map library, on mobile, load that map library, and that can be a way that you can handle it. But that's actually a great transition into what we're doing next. So let's keep going and we haven't been going for too long right now. This is gonna be the home stretch as far as platform specific functionality in our React native web app. After that we're gonna do a very brief wrap up where I talk about considering how I would recommend you think about whether to use React native web or whether to use separate React native and React web applications. So let's dive into platform specific functionality. For this I don't have examples in this code here. But what I do have is the Shirley code base. So I'm gonna pull up Shirley, my to do list app, and we're gonna take a look at it there. And I do want to show you the app first so you can see the conditional stuff we're gonna be looking at. So this is Shirley, it should look very familiar to you. Here's my sidebar, I've got little icons added in, that was kind of fun. You can see my centered column over there. But I've got these to do items here. I can add in to do items, I can click on them, I get a little detail screen, I'm on the child screen with the URL where I can go back. And I can edit my to do's. I work in this all day. Oh, a little visual issue there, that's interesting. Oh, nothing's perfect. All right, so in Shirley here, let's take a look, and I want to show you on mobile as well. Let me pull up my actual phone. So I have my physical phone hooked up to my computer. Here's the video feed coming over from it. And so this is Shirley, the native application running on my phone, and I'm tapping over there. So let's look at the sidebar. So in the sidebar here, you can see over here on the web, I have a download on the app store button. Because that's nice, if someone's using Shirley on the web, I want them to know that it's available on the app store. Now, not if you're on a phone, because if you're on a phone on the web, I want them to know as well, but if you're in the native mobile app, I don't need to have the download on the app store button, they already have the app, they're in the app. So that's a conditional. This content could display on both, but I conditionally want to display it only when we're on the web. So let's take a look at how I did that. Let me pull it up here. Yeah, here is the Shirley code. So this is the about, no, it's the... Navigation drawer. So here, and again, this is the first time I built it, and then I extracted the content of our workshop out of this application. So a lot of this should look familiar. So check out what I have here. From React Native, I'm pulling in this API called platform. And then up here, I say platform.OS, and I compare it to web. So this is a platform with functionality built into React Native. It allows you to... You can actually check iOS or Android on there, but when you're using React Native Web, web is an option as well. And because I like to create tiny little variables and stuff like that, I just create an isWeb constant that's true or false, depending on if this matches. Well, let's see where that's used. And down here in the drawer, I just say if it is the web, then show the download on the App Store button. And that's pretty much it. It's just a conditional, where we detect the platform that we're on, and we either show it or don't show it, depending on the platform that we're on. So there's one change. And this is something you can think about, just because your app is available on web and on mobile, it doesn't need to be identical. So maybe you have something that's easy to add on mobile, but maybe it's just not possible on the web. Or maybe it's hard. Maybe it's gonna take you some work and you would like to make it available to your users on mobile, and then you'll see if you get to it on the web. You can add a conditional around it. You can add a little placeholder that says, in this case, it's a button, you don't need to. But it's like, hey, if you would like this functionality, download the mobile web app. Please don't ever do that, though. One of the nice things about React Native Web is you can have an awesome website and mobile sites. You don't need to do that thing where you tell people it's better in the app. The website and mobile app are both great and both work really well. So this is one approach to different platform specific functionality is by having just conditionals around it.

26. Handling Conditionality and Platform Differences

Short description:

Let's explore some examples of conditionality across platforms. We'll look at handling different scenarios, such as linking to the website, sharing functionality on mobile and web, and checking if certain APIs are supported. We'll discuss the differences between iOS and Android in React Native and how libraries like React Native Paper help bridge those gaps. Additionally, we'll address the question of whether it's better to have a separate implementation for the web or cover it using React Native. Now, let's dive into some specific examples of conditionality, including sharing with friends and identifying if the share API is supported. We'll explore how to handle cases where the share API is not available and implement fallback options. This will allow us to provide users with a way to share, regardless of the platform they're on.

Let's look for other examples in Shirley. Let's go to the about screen. I'm gonna go back from here. Oh, wow, something interesting is going on. Yeah, about screen. Pull it up. All right, so here's the about screen. On web and on mobile. You see on, what do we got? Made by me get support, ways to say thanks, Shirley web. So you see this is kind of going back in the opposite direction. So when you're in the mobile app, I link you over to the website just so you know that that's available as well. When you're on the website, I don't need to do that. So that's another conditional. Let's take a look at that and then I'll get to that question in the chat. Again, I check platform OS equals web. And then I say, Oh, if we're not on web, show the button that goes over to the web. Let me look on chat here. Vicky says, from your experience, does it make sense to try to cover the web version of the app using React Native? Or is it better to have a separate implementation? To the same topic, have you ever experienced issues where you could not achieve what you wanted in either iOS or Android? The separate web version, and we're going to come to that shortly in the wrap-up for the workshop. So I'll come back to that one. And, but feel free to ask a question again if I don't fully cover it at that time. Have you ever experienced issues where you could not achieve what you wanted in either iOS or Android? In the apps that I've worked on, I haven't run across that. I've certainly run across differences. When I was doing styles scratch in a recent React Native professional consulting application, it was so interesting. I got a design with a drop shadow for an element like great shadows. And then I found like, wow, when you're coding this from scratch, the way shadows work on iOS and Android in React Native is very different. And so that was a lot of working around that and a lot of back and forth, the designer to say, oh, here are the constraints of these different platforms. So there can definitely be work across the platforms. One of the nice things that a library like React Native paper is they already have those things working on both platforms. Generally for React Native, a lot of functionality targets both. I mean, if you have something that's very specific to one platform or the other, like something that only exists on iPhones, there might be a library that's specific to that and you may need to put a conditional in that place. But for the, I haven't written apps that very specifically integrate with those very low level things. Generally, there's a lot of really great React Native open source libraries that wrap over those iOS and Android differences. So iOS and Android differences, I haven't run into cases where I couldn't achieve what I wanted to across both of those. And again, for your other question about web, we'll come back to that shortly in the wrap-up. All right, so now let's take a look at some other conditionality here across platforms. Let's go to the ways to say, thanks screen, go into here. So this is again, shirt free app, I'm not trying to plug my app, you can use it if you like, if you wanted to do this, but it's very low features, cause that's what I wanted. Anyways, so the first button here is share with friends. And so let's see what the options are. So on mobile when I tap on share with friends, so I get that built in iOS share sheet. So that's pretty nice. Actually, interestingly on the web, I just pulled up Safari here, which I barely ever use, but on the web, on desktop, when I say share with friends, the little share interface pops up in here as well with all my family members with their full names. That's fun. That's okay. So this is actually a web share interface. This is an API in some browsers and I haven't checked browser compatibility recently, but I believe in Firefox, that's not the case. So when I click on share with friends, it just takes me to the Shirley URL just to give you a URL to be able to share. So that is not available in Firefox currently. I haven't tested in Chrome. So let's see how that works. So there's a share API on mobile and in some webcases, but not in other webcases. What do we do in that case? Let's find it here. So here's my share button, share with friends. And I created a handle share function because there's always some way to share, it just how it happens differently. So I handle share here, I have is share supported? And I say, if that is supported, then call this share API, which comes out of react native that's built in Iraq native, interestingly. But if share is not supported, then I just open the URL using this linking API, which is also available in react native that just opens a web URL. So how do I identify if share is supported? So it would be nice if the share.share library always worked. If there was a way for it to always work, that'd be great. I don't need a conditional. Or it's nice, sometimes we'll see, we'll see down below here in a second. Sometimes a library will tell you if it's supported on a platform or not. In the case of share here, it did not actually tell me. So I didn't need to do my own logic. So what I had to do was, just by experimentation on different platforms, I needed to find out if share is supported. So what I found was, if we're not on web, share is always supported. There is an iOS shared API, there is an Android share API, so we're good. What about if we are on the web? We are on the web. We need to do, I think it's called feature sniffing. It's a web approach where you just basically check and see, is that API available? So I say, if Navigator.share is available, then share is supported. So this is interesting. Notice, I don't need to use Navigator.share directly. If it is supported, I just call share.share. But if Navigator.share isn't available, it just blows up. So unfortunately the React Native library isn't checking that for me. I need to do my own cautious check before I'm willing to call it. So what I've found is that this is the condition I needed to know if it was safe to call share.share, which is basically when it blew up, I found what I needed to check. I can't just always check Navigator.share because Navigator is a web browser thing. It goes all the way back to Netscape Navigator for old-timers like me. So if I'm not on the web, I don't need to check that. I just need to know I'm not on the web, I'm good to go. So this is an example of a more sophisticated conditional you might need to do and have a fallback approach. It's not quite as good, but at least gives the user something rather than nothing.

27. Conditionality in Library Usage

Short description:

There is a store review API that allows users to write reviews for your app in the App Store or Google Play Store. The availability of the review functionality depends on whether the user is on the web or not. It is recommended to check if the review functionality is available before calling it. Additionally, some libraries provide support for checking if they are supported, allowing you to add conditional checks around library usage.

Let's take a look for another approach here. Another case of conditionality. So I'm going to keep unlocking my phone screen here. You see, I have this rate or review the app button but it doesn't show up on the web. Let's see what happened. I think actually, I think I broke this. So yeah, this is not currently working. So I'll need to investigate that to see. But I can tell you what I was doing and I know I've seen it work at least once. So there is a store review API. This actually comes from an Expo package. Expo Store Review. And what that allows you to do is to send users to the App Store or Google Play Store so they can write a review for your app. This might be why my app doesn't have any reviews in the App Store currently. And so you can call that. In this case, store review actually has a function you could call to see, is it available? If await store review.has action, call store review.request review. So this is a function in the store review library where it will tell you, yes, I can send the user to a review. It seems to be imperfect here. So part of it is if you're on the web versus not on the web. Actually, this is interesting, I'm remembering here, it's kind of interesting that the button is not showing up. So handle review. Yeah, oh, so check it out. I have two levels of conditions here. So if I'm not on, it's only if I'm not on the web that I show the rate or review the app. I felt like it was kind of tacky being on the web interface to ask people to rate or review the app. And it wouldn't even make sense, like how do I know whether you have iOS or Android? Probably I don't need reviews that bad, probably I should just let you, and again, I don't have an Android app built yet, but the possibility in the future. So I don't want to send people from the web to the app store to review, so I just hide it entirely. But then I found also there was some conditionality here and actually store review encourage you to always check has action before you call request review. There's configuration and this may be what I messed up in the configuration for your app. You need to say here is the URL of the app or the ID in the App Store in the Google Play Store, and that's what allows Store Review to know where to send the user. So it's only in the case that that's there that this returns true, resolves to true asynchronously, and then you can call a request for review. So that was a lot of details specific to Store Review, but my point on this is that you may be using a library where you can ask the library itself, are you supported? And if it tells you yes, then you're good to go. And we saw in a contrasting example, maybe the library will let you call it and it will just blow up, in which case, you may need to add your own conditionally around, conditional check around it instead. So these are some of the different scenarios you can run across.

28. Internationalization and Secure Storage

Short description:

React Native internationalization can be achieved using ECMAScript internationalization API. Expo SecureStore provides secure storage for credentials on mobile, but there is no equivalent for web browsers. Storing tokens in browser cookies is more secure than using local storage. However, each approach has drawbacks and requires careful consideration of security factors. Web developers need to research and choose the appropriate architecture for securely storing credentials. It is important to consult OWASP guides and resources from Auth0 and Okta for token storage recommendations. Security is a crucial aspect of web development, and organizations should make informed decisions to ensure data protection.

Jan says, you have hard-coded text in your app. How does internationalization work in React Native? Yeah, let's take a look at that because I finished the other train of thought. The React Native apps I've worked on have not had an internationalization requirement. It's something we raised because we know that's important in the last consulting project, React Native project that I had, and they decided specifically, they were a real estate company focused in the US, and so they decided at the time it wasn't strategic to put the time into internationalization either on their web app or on their React Native app. Let's take a look and see. ECMAScript internationalization API. Basically, honestly what it comes down to is I would check the React Native docs to find out about internationalization on React Native. I know it's available. I think it looks like it probably uses basic ECMAScript APIs. I imagine IAT NeXT is probably available because that's a very common library, and I know we're using it on the React web application that I'm building right now. So, I do not know as far as internationalization, but I know it's available for sure because there's a lot of React Native apps that use that. Cool! The last thing that I'll mention is there may be some cases where there's architectural differences between the platforms. This would be an example of something that's just not available, and you just have to do it in a different way on the web. So, let me show you an example of that because this is important to know about because this can affect your architectural planning. Expo SecureStore. Expo SecureStore provides a way to encrypt and securely store key-value pairs locally on the device. They tell you what underlying technologies are used for that. So this, if you have credentials, including an access token or refresh tokens, a secure store is very important to use that on mobile to store it because there are other data storage ways for data that doesn't need to be secure like that. There's built in sandboxing in mobile, so any app can't just reach over willy-nilly to another app to get its data, but it's not safe enough for credentials. And so you wanna use Expo SecureStore. Or if you're not using Expo, I think React Native Keychain is the name of a library that's very well thought of and used for that. And so that's what I use in my app here on iOS for logging in. You log in, you have an access token and it's stored in Expo SecureStore. So this is not available on the web. So what do you do on the web? So the most important thing when it comes to security is to understand why. So the reason Expo SecureStore and similar technologies are not on the web is that there is no equivalent for secure storage in web browsers. This is very important. I did research on this in a research week a couple of years ago because I really wanted to deeply understand this across all these different platforms. Architecturally, there is not a way to store this information securely in a browser that's encrypted and protected like that. And so you can't do it, you cannot do the same thing. This opens a real can of worms. And so it's like, well, what should you do? I certainly can't explain it very well off the cuff. And I haven't actually published this because I'm not a security expert and I'm not a lawyer and I don't wanna be held accountable if I say something the wrong way and your company builds something and gets exploited. So when it comes to front end react applications or React Native web applications running the web, you need to do research on the security there. I will say what I'm comfortable saying is that browser cookies are more secure. There are downsides there. There's things you need to mitigate there as well. But generally, so the thing that I would not advise, but people do do this, is to use browser local storage to store an access token. This is common. There's a lot of resources online that teach that, but it's not secure and it's not safe. I mean, it's not, let me not mitigate that too much. That is not recommended as a way to securely store things. I will say, I'm not gonna show you the code. I have a big comment, disclaimer in this open source code that you can see if you go into it. So how do I store the authentication in the app? Well, for a to-do list app like this, I do store it with local storage, but I do not recommend that. It's only because this is a trivial side project just for to-dos that I store that that way. I feel like the risk level is low enough, but I'm not advising you to use local storage in your own react web application or react native web application. It is much better to use cookies but look into the limitations of cookies as well. So on the web, you would need to approach things with a different architecture. There's not just a secure storage API you could use. You might need to host it, your react native web app, through a server side framework. I know there are ways to get Expo with web to work with Next.js, for example, if you're using Next.js. So the point is there is a can of worms. This is a great example of a platform difference where it's like there are no easy options on the web and you're gonna need to take some time into it and you need to really think hard about the security factors there. And my app is not an example. Do not use my app as an example for how to store credentials. And I have that disclaimer in that file as well. So I apologize I don't have simple, easy answers there, but it's life of a web developer. Web has a lot of benefits, but that's something we need to look into as a trade off. Cool, okay, so hopefully that makes sense. I'm gonna check the notes here. Processing storage is used though. It should be only cookies for tokens will work. Also has drawbacks, look up OS guides to store JWT. I would agree with Carol there. Fully shooting down anything that was shared in chat there, but all the approaches have drawbacks. Yeah, and I do recommend looking up OWASP guides or other guides about token storage. There's great resources from Auth0 and Okta on token storage recommendations. There's even things about using web workers and service workers. And a guy that, the last client I was at, had done that before, but actually I couldn't find any examples online of how to use web workers and service workers to more securely store tokens. Maybe other people that don't wanna put their information out there and be at risk of liability. So yeah, security on the web for client rendered stuff is a challenge for sure. So, thank you all for sharing some thoughts in the chat there. I will say a client project that I was on, I chose local storage for storing the tokens. And then afterwards I was like, oh, I found out that that's not good. And so I raised it to their security organization. And I said, my bad, there are downsides here, I cannot choose for you. Like you as an organization need to decide what to do. And we did a really deep dive into security. They thought through it and their organization made a choice about what to do. And I won't share the details cause that's getting confidential. But so I have done something that as a consultant afterwards, I was like, that wasn't secure enough. And so I went to them to raise it to them so that we all together could work together to decide what was the right thing Okay, that was a real leap dive on security there. But if you got nervous about web token security, then mission accomplished, I'm glad that you are. I don't, I don't feel bad. And that's why I said that I made a mistake on this and I felt bad afterwards. Maybe I shouldn't phrase it that way. We are all growing and learning. And so learn what you can at the time, do what you can to make things as secure as you can, raise trade offs to your organization so that organization leadership can decide but as a professional security is so important. If the last 10 years have shown us anything in software development is that we need to be more secure.

29. React Native Web and Choosing Between Apps

Short description:

I recommend looking into secure token storage on the web and mobile. Consider the trade-offs between React Native Web and separate React Native and React Web apps. React Native Web is beneficial when you need both a web and a mobile app, especially if they are largely the same. However, if the apps cater to different audiences or have significant differences in functionality, separate apps may be more suitable. Additionally, use React Native Web if you don't require fine-grain control of HTML. It provides an abstraction over HTML details, which can be beneficial for some projects but may limit access to specific HTML elements and attributes. Consider your app's needs and priorities, including accessibility and semantic HTML, when deciding between React Native Web and separate apps. Remember that non-UI code can still be shared between React and React Native. As for choosing between an Electron app with Next.js or a React Native app, it depends on the specific requirements and context of the project.

And so I would recommend looking into secure token storage on the web and on mobile, and we could all do to level up our security knowledge. So it is a investment well-spent and just I personally believe ethically it's just so important and it serves your organization, your employer as well and your user as well, maybe most importantly.

Okay, let's come way back from that security thing and let's go to the wrap-up phase. And then after that, I can stay on for questions if anybody has anything you'd like to ask about but I'll point you to places that we can stay in touch. Thank you for exploring all this code with me. So we've seen React Native Web in use now if it was unclear what it even is, hopefully it's very clear now or at least what it could be, what you might want to investigate in the future. So when would you want to use it? And this goes back to a question that was asked earlier, I think by Vicki. Okay, React Native Web is an option. Should you always use that instead of normal React for the web? If you've got a React Native web app, like is there ever a case where you'd want a React Native app and a separate React Web app? I think there is. I think there's trade-offs to choose between the two so let's talk about it together. And I would love to hear if anyone wants to share in the chat after this. I would love to hear your thoughts on the trade-offs as well. And certainly, the most important thing is if you're looking to start a project with a new React or React Native, investigate, check it out to see if you'd like to use React Native Web or if it's better to use it separately. And you might go either way and ask the community. The React Native community would be happy to chime in and I'd certainly be happy to share my thoughts as well.

Yeah, so here's my thoughts. So certainly, maybe the most obvious point is I would use React Native Web if you need both a web and a mobile app. But the reason I bring this up is you might not need both. You might think, oh, React Native Web exists, I might as well get a web app and a mobile app. But we've seen some of the challenges. It's not free to have a web app version of your mobile app, like security is a challenge. And testing things on different iPhone screen sizes, different Android device sizes. Like there's work involved, like there are downsides. And so, I mean, there are places and areas where like mobile app only is fine, or web only is fine and that gives you everything you need. And so, there will always be a cost to supporting both platforms. And so, and React Native Web doesn't give you that for free. So, think about, do you need both? You might only need web, you might only need mobile, or at least for this stage of your organization or your business, you might only need one. But if you do need both web and a mobile app, I would say if it's largely the same app on mobile and on web, that's a good reason to use React Native Web. If it's largely different, maybe not.

Some cases I can share are, one of my first contracts in consulting was for an app where the Native app was for end users, it was through a hospital system. And the web app was for hospital administrators. So, it was different audiences. And so, there was very different, I mean, same backend data, but it was very different use cases. So, they didn't need to look the same, they did not, you know, features by default did not get added to both. If anything, it was a very different way of looking at the same data. And so, React Native Web would not have provided any benefit here because it's entirely different screens for entirely different users on mobile and on web. They should be built separately. Now, Shirley is a great example of, it's the same to-do list app. I want it to look almost exactly the same. 99% of the UI and functionality is identical. A lot of benefit to React Native Web. I was talking on the Infinite Red, I guess it's, I think it's just a React Native podcast, through Infinite Red, and one of their developers, Robin, shared about how she had done a React Native Web application and she actually had, there was some screens and functionality that was fairly different across mobile and across web, but she found like, no, yeah, React Native Web still provided a lot of benefits because there was a lot of screens that were the same. So there would be more conditionals in that case, you know, render out this screen versus that screen on the different platforms. But I pass along her recommendation for you that like, even if it's largely the same on mobile and on web, you can still find a benefit from React Native Web versus having to re-implement them from scratch.

The other thing I should say, and we didn't get into this in detail is, use React Native Web if you don't need fine grain control of HTML. So when you're coding HTML directly, even using React where your JSX is outputting individual HTML elements, there's, you know, you choose like, okay, what what semantic elements am I using? Am I using header and main and aside correctly? All of the accessibility attributes and things like that, is it a button, it looks like a button, but it's really a link, so I should use an anchor tag but style it. All those different concerns for the sake of semantic HTML and for the sake of accessibility. So that's the mindset when you're coding for the web, including React for the web. For React Native Web, it's an abstraction over those details and so you don't get access to them. And so if you're gonna feel frustrated by that, maybe it's not gonna work. Or if your app requires you to have access to that, that's not gonna work. One example, I noticed that a pressable, at least at one point in time when I checked it, the pressable component for React Native and React Native Web was not implemented as a button. It was implemented as a div that had the right ARIA attributes to make it indicate as a button and stuff like that. And if you know about accessibility on the web or semantic HTML, you would say, no, that needs to be a button. Like, that's is not okay. Like you should not prefer a div with ARIA attributes. You should prefer a button. So there was an open GitHub issue about that. And the reason it was implemented that way in React Native Web is there was a visual issue in some environment, I forget, where a button was causing a problem. So this is one of the things where when you're coding HTML and you're coding one specific element on one specific screen, you can use button. Great, you're good to go. But React Native Web is translating every pressable in every React Native Web application in the universe into HTML. And so for them, if there's some cases where a button won't work because there's a bug in some browser, they can't use it. Or maybe they can make it conditional or something like that. I think they were planning on that at some point. So when you're working through an abstraction like React Native Web, you can't access the HTML as directly. You can contribute to it. And so you could find like, oh, I wanna improve the accessibility here or the semantic HTML there. And you can help contribute to React Native Web. It's an open source project that would be really appreciated. I would appreciate it. I got my React Native Web app. But so that's something to think about. Like for your needs. I mean, I think everybody should prioritize accessibility in their applications, but for your needs of your app or your business, your organization, do you need that fine grain control of HTML? Is it gonna really get in your way to be running through the React Native Web abstraction. So think about that. Maybe do a proof of concept, maybe build one screen in React Native Web and try to get it fully accessible, fully semantic to your standards for what you need your web app to be like and see if React Native Web will get you there. And you may find that, you know what? It's worth the cost for us to maintain a separate React Web application because we get full control of the HTML. At that point, you've made an intentional decision. You've decided I got a React Native app and I've got a React Web app for a reason and you know why you're taking on that extra cost. And in a lot of cases, it does make sense to do it. So those are my thoughts. But those are all things where I would say, those are cases where you'd say, why sometimes you might choose React Native Web and sometimes you might choose to have a separate React Native and React code base. And of course, any code that's not UI specific can be fair. So your business logic, your data layer, custom hooks of many different kinds, third-party JavaScript libraries, first-party internal JavaScript libraries, those can be shared across React and React Native. So maybe that's the level of sharing that makes sense for your application, but it's a separate web UI for mobile UI. I see some thoughts in the chat here. Let me read this. Jane says, what do you prefer, an Electron app with Next.js or React Native app? That's a great question because Electron is an option on the web. Well, so let me think about this.

30. React Native Web and Abstractions

Short description:

Electron is an option for desktop, laptop, Mac OS, Windows, Linux to run an app and you can run Next.js or some other React app inside of it. React Native runs on mobile and desktop as well. React Native for Windows and React Native for Mac are maintained by Microsoft. React Native Web is a great option if you want to build for both web and mobile at the same time. Styling is a challenge in React Native as it is not as powerful as CSS. React Native allows you to focus on delivering features to iOS, Android, and web without worrying about the implementation details. React Native web and tools like React Navigation and React Native Paper provide abstractions that make development more efficient.

Electron, if I'm saying correctly, Electron is an option for desktop, laptop, Mac OS, Windows, Linux to run an app and you can run Next.js or some other React app inside of it, whereas React Native runs on mobile. And oh, and React Native runs on desktop as well. So Microsoft maintains React Native for Windows and React Native for Mac. I don't know about Linux and you can easily add that into a React Native application. So I don't know. I do know that personally for me, I use a lot of React Electron applications and they're good enough for me on the web. I haven't tried to add React Native Mac functionality to Shirley. I just use the Shirley web interface and actually use a little command line tool that creates a really trivial Electron app that wraps the React Native web interface. So yeah. I don't think Electron runs on mobile. And so maybe probably that's not what you're asking about, but so on mobile, I would use React Native. I haven't used any of the other Ionic or other kind of web wrappers on mobile, but they tend to not have a favorable opinion amongst mobile developers. React Native tends to have a more favorable opinion. On desktop, web-based things tend to be fine for my purposes. And so Electron or just web apps tend to work for me personally. You see someone said that session storage is the recommendation. I will say that I've seen downsides to session storage as well for token storage. So I personally am not saying session storage is obviously a totally fine for use. I can't describe it too well off the top of my head, but I just encourage folks to keep investigating. Yeah, as Karola said, session storage alone is vulnerable. Again, some more things about security, I'll skip over those. Styling is not that powerful in React Native as it is in CSS. So I often find myself struggling with this. Absolutely, that totally makes sense. CSS isn't brought over automatically and not everything is in there. The reason there's a number of, well, I mean, there's a ton of styling libraries on the web as well, but one of the reasons there's so many styling libraries on React Native is to work around built in limitations or rather to say, again, React Native is creating a universe from scratch. Like they're building another levels of abstraction with additional functionality on top of it. But styling is a challenge on React Native. And I talked about the issue I had with shadows, so like just getting a shadow is challenging because Android and iOS have very different concepts and React Native uses the native functionality under the hood. And so they are building with what iOS and Android gives them, which isn't always identical. Yes, securing the web is hard. That's why Josh is not comfortable in telling us how to do. Absolutely. Go find those folks that are security researchers that have the legal protection and the insurance to be able to make recommendations and are more informed than me to be able to make recommendations or hire me from a project and then I'll give you recommendations with qualifications appropriately. Jan says, Electron is running on mobile as well. I did not realize that. That is very cool to hear about. And I might be more likely to reach for that than something like Ionic. So I'm gonna write a to-do and Shirley, literally, check out Electron on mobile because I wanna learn about that. I haven't reached for it before, but I like to know these options that are out there for folks. Certainly when folks ask questions. So I appreciate Jan, you sharing that as well as all the other stuff that folks have been sharing together today. That's cool. All right, yeah, if anyone else has thoughts on when you might use React Native Web versus separate React in the web, definitely feel free to share that in the chat or in Discord. Jan said, I never was in touch with React Native before, but you fixed me on it. Thank you very much for this great workshop. You're very welcome. I hope others have gotten benefits here as well. React Native is different than the web, and yet there's a lot of overlap. And certainly when you're in, and I guess this is another positive side. In general, this is what I say about React Native organizations. If you're using React already, there's so much about React Native that is so great, and so much that carries over the mental model, the programming models, so much shared code, even if you're not using React Native Web. So any organization, I mean, honestly as I thought in consulting, the last place I worked did a lot of native mobile development as well as React Native. So when do we recommend which? The simplest thing I came down to was the best case we're using React Native is if you already have React developers and you don't yet have a mobile app and React Native would fit your use cases, consider React Native. React Native Web is a great use case for if you don't yet have a web or mobile app and you wanna build for both at the same time, reaching for React Native Web could be a great option in that case. Charlotte's asked for a concrete link on Electron Mobile. So yes, please do. Share that if you have that and I'll Google it and if I find it as well, I mean, I imagine Jan will share that link if it's available but yeah, I'll share in Discord as well afterwards. Quiano asks to export or not to Expo or maybe any case we should eject. So I've used Expo only on side projects, not on professional projects. So I can't speak to that too strongly. I know the folks at Infinite Red, which is extremely experienced React Native consultancy, they use Expo by default. And one of the great things about Expo is I've shown the case here where we're just writing JavaScript code but Expo does have ways in the last couple of years where you can build in native code, where people can create config plugins so that native code can be added in. And so that way you're not custom tweaking iOS files and Android files and things like that. So that is an option with Expo and there is still an option to eject out of Expo as well. So there are others out there who have better knowledge than me about Expo versus React Native CLI. So I'll defer to them. Okay, let me see what else I have. We are still in wrap up, but only a little bit left. Conclusion, so this is a big picture thing about abstractions. Why did I work like this for Shirley? Why did I look into React Native web and what drew me to it? So a lot of folks in software development are focused on doing more. What is the latest greatest thing? What's new, APIs? What's new technologies? GPT just came out this week, that's mind blowing and exciting and worrying, that's all I'll say about that. But people doing things that have never been done before, and some people do that, I'm really glad they do. People invent new UI frameworks like React or new JavaScript build systems. That's really neat, I'm glad people do that and I like benefiting from their work. But doing more is not the thing that gets me the most excited in software development. For me personally, what gets me more excited is doing more with less. I love abstractions that allow us to me as a consultant and when I've worked at companies and people worked in to companies, just let me build the feature I wanna build. And if you can take care of any of those accidental complexity as the technical term, any of those things that I don't wanna have to worry about, like just let me get right to building the feature for my users that I need, that's beneficial. And React Native totally falls in that category. It's a lot of work to learn iOS and Android separately and build the same thing in both. Or it's a lot of money for a company to hire experienced people that know both of those and a lot of coordination to get the same feature added in to both of them. That's a lot of things that's not delivering the features to users. One of the great things about React Native and there's downsides as well, for sure there's trade-offs. But one of the great things about React Native is it allows you to focus more on, let me just get those features to the users and can you make it just work on iOS and Android. And one of the great things about React Native web is it adds web into the mix as well. Trade-offs, of course, but it gives you an option to say, let me deliver features to iOS, Android, and web and not have to worry about the implementation details and re-implementing something from scratch. So that's what gets me excited about React Native web as well as tools like React navigation and React Native paper. Having the option to not have to build those things from scratch unless you need to. It works really great.

31. Conclusion and Stay in Touch

Short description:

React Native Web is a great tool for building mobile and web apps. It allows you to do more with less code and provides abstractions that are beneficial to organizations. The workshop webpage has a full write-up of everything we covered, as well as the starting and ending repo for download. Stay in touch with me and Test Double through the newsletter, and join the Discord servers for React and React Native discussions. Cordova and PhoneGap are options for building native mobile apps with web views. Thank you all for joining the workshop, and feel free to reach out with any questions. Cheers!

And so to the degree that this is a fit for you, if that's your wiring, if you are at a small organization, maybe a nonprofit organization, maybe you're an internal team and your whole job is not making an app, but maybe these abstractions let you build something that's useful and saves you work and is beneficial to an organization. So I love tools and ideas that equip people to be able to do more with less. And maybe that's a fit for you, or maybe not today, but maybe sometime in the future.

Again, to summarize, this is the webpage again that I sent you to at the start. It'll be in Discord afterwards as well. This is the workshop webpage that has a full write-up of everything we walked through, as well as the starting and ending repo that you can download. If you don't wanna code it all yourself, just download the ending repo and build your app off of that. It also has ways to keep in touch with me personally and with Test Double. So again, Test Double is the consultancy where I work. We work in React Native, React and on the web as well, and a number of different web technologies. And if you wanna hear from us, you can sign up for testdouble.com slash newsletter. I've got some blog posts and some screen casts that are, I'm planning on working on in the new year to share with you there. I also have, you know, Git Nation has a Discord server. I also have my own Discord server where I talk about React and React Native and testing especially. So there's, this would be a good place if you wanna stay in touch with me and with a number of other people that work in React Native, especially because that's what my screencast is on. I mean, what my live stream is on. There's a number of React Native people and they're chatting. So that's a great place to stay in touch. That's linked from the webpage or from the slides if you get the slides later.

Yeah, you all have been asking so many questions in the chat already, I'm gonna look down there but, but we are done. Thank you so much for joining. Feel free to head out 15 minutes early if you want to, or if you need to, but I'm around for the next 15 minutes and for any questions that you might have. And let me take a look at the chat. Oh, Jan found that it turns out Electron is not available for mobile after all. Okay, yeah, no worries there but yeah, there are tools I'm aware of. Ionic is the name of one tool that allows you to use web code not, so React Native is JavaScript but it turns into native widgets. There is no web view, there's no browser view in React Native. That's something important that not everyone knows about. But there are tools for building native, native mobile applications that do use web views. Ionic is one of them. Cordova and PhoneGap are another. I think they're the same thing but one of them is open source and I think there may even be others. So there are tools that let you have web views so that you are using DOM elements. I think when I've looked at them, they have other kinds of abstractions as well. So I don't know if they allow you to just drop your React application directly into a native mobile app. So others of y'all might know more than me. So I know that, yeah, I know that Cordova and PhoneGap are options. If you don't want to use React Native, you wanna be doing web web. There is a consulting project I ran across recently where the client was like, yeah, we just have React components and we want to use them on mobile. And it's like, okay, React Native won't work because those components are web components running in our DOM elements. So in that case, I wasn't directly involved but the consultants I work with did advise, I think Cordova for that case, to be able to use those because they were not able to re-implement in React Native. That wasn't a fit for their use case. Corola says, thank you and see you tomorrow in the testing workshop. That's great, I'm glad that you'll be there. I'm excited about leading a workshop on React Web Testing tomorrow. I don't know if registrations are still open or if people's schedules are still open but I'm looking forward to presenting that, as well. Yeah, thanks for the thanks everyone. I've really enjoyed it. There's been a lot of engagement in the chat. Even you all answering each other's questions and I really appreciate that, as well. But yeah, that's React Native Web. Try it out yourself or fork my code and build off of it and see what you think. But whatever your coding looks like in React on the web and on React Native, yeah, I hope it's helpful. And feel free to reach out any time, email, LinkedIn, Discord, anything like that. I love chatting about these things and I'd be glad to help you out and field questions or put you in touch with people who have answers to the questions, as well. But thank you all for joining. I've really, really enjoyed it and had a great time. Thanks. I'm not gonna click close just yet. I'll just leave it another minute in case anybody asks anything. Feel free to head out, folks. Thanks so much. Cheers with my sparkling water. Many of y'all may be in Europe, I don't know if this is a thing in Europe. But in the US, sparkling water has been a thing for a number of years. It's silly, I think sparkling water has been much more of a thing in Europe. I didn't get to come to Berlin for the conference, unfortunately. I did get to come to London for React Advanced London. I was very excited about that. This year was my first visits to Europe. I got to go to Poland for React Native EU. That was very fun, and then I got to go to London for React Advanced London. So it was so cool. As your stereotypical American who has only been over in the Western Hemisphere, it was just so neat to get to visit Europe. Everyone was so great, and folks in Poland were patient with me, not knowing Polish, and I tried my best to account for things and to be helpful, but yeah, it was just so neat to visit. I really, really hope to be involved with Git Nation conferences in the future. I get to visit London again, maybe Berlin next year. But yeah, so thank you for accommodating my time zone. I hope this time worked out okay for y'all as well. And yeah, I can't wait for React April and talks to go up. I'm looking forward to checking those out and seeing which ones I can learn from there. Thanks so much, everyone. I will be in Discord at least for the next week in the Git Nation Discords for any other followup questions you all have there.

Watch more workshops on topic

React Summit 2023React Summit 2023
170 min
React Performance Debugging Masterclass
Featured WorkshopFree
Ivan’s first attempts at performance debugging were chaotic. He would see a slow interaction, try a random optimization, see that it didn't help, and keep trying other optimizations until he found the right one (or gave up).
Back then, Ivan didn’t know how to use performance devtools well. He would do a recording in Chrome DevTools or React Profiler, poke around it, try clicking random things, and then close it in frustration a few minutes later. Now, Ivan knows exactly where and what to look for. And in this workshop, Ivan will teach you that too.
Here’s how this is going to work. We’ll take a slow app → debug it (using tools like Chrome DevTools, React Profiler, and why-did-you-render) → pinpoint the bottleneck → and then repeat, several times more. We won’t talk about the solutions (in 90% of the cases, it’s just the ol’ regular useMemo() or memo()). But we’ll talk about everything that comes before – and learn how to analyze any React performance problem, step by step.
(Note: This workshop is best suited for engineers who are already familiar with how useMemo() and memo() work – but want to get better at using the performance tools around React. Also, we’ll be covering interaction performance, not load speed, so you won’t hear a word about Lighthouse 🤐)
React Advanced Conference 2021React Advanced Conference 2021
132 min
Concurrent Rendering Adventures in React 18
Featured WorkshopFree
With the release of React 18 we finally get the long awaited concurrent rendering. But how is that going to affect your application? What are the benefits of concurrent rendering in React? What do you need to do to switch to concurrent rendering when you upgrade to React 18? And what if you don’t want or can’t use concurrent rendering yet?

There are some behavior changes you need to be aware of! In this workshop we will cover all of those subjects and more.

Join me with your laptop in this interactive workshop. You will see how easy it is to switch to concurrent rendering in your React application. You will learn all about concurrent rendering, SuspenseList, the startTransition API and more.
React Summit Remote Edition 2021React Summit Remote Edition 2021
177 min
React Hooks Tips Only the Pros Know
Featured Workshop
The addition of the hooks API to React was quite a major change. Before hooks most components had to be class based. Now, with hooks, these are often much simpler functional components. Hooks can be really simple to use. Almost deceptively simple. Because there are still plenty of ways you can mess up with hooks. And it often turns out there are many ways where you can improve your components a better understanding of how each React hook can be used.You will learn all about the pros and cons of the various hooks. You will learn when to use useState() versus useReducer(). We will look at using useContext() efficiently. You will see when to use useLayoutEffect() and when useEffect() is better.
React Advanced Conference 2021React Advanced Conference 2021
174 min
React, TypeScript, and TDD
Featured WorkshopFree
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
React Advanced Conference 2021React Advanced Conference 2021
145 min
Web3 Workshop - Building Your First Dapp
Featured WorkshopFree
In this workshop, you'll learn how to build your first full stack dapp on the Ethereum blockchain, reading and writing data to the network, and connecting a front end application to the contract you've deployed. By the end of the workshop, you'll understand how to set up a full stack development environment, run a local node, and interact with any smart contract using React, HardHat, and Ethers.js.
React Summit 2023React Summit 2023
151 min
Designing Effective Tests With React Testing Library
Featured Workshop
React Testing Library is a great framework for React component tests because there are a lot of questions it answers for you, so you don’t need to worry about those questions. But that doesn’t mean testing is easy. There are still a lot of questions you have to figure out for yourself: How many component tests should you write vs end-to-end tests or lower-level unit tests? How can you test a certain line of code that is tricky to test? And what in the world are you supposed to do about that persistent act() warning?
In this three-hour workshop we’ll introduce React Testing Library along with a mental model for how to think about designing your component tests. This mental model will help you see how to test each bit of logic, whether or not to mock dependencies, and will help improve the design of your components. You’ll walk away with the tools, techniques, and principles you need to implement low-cost, high-value component tests.
Table of contents- The different kinds of React application tests, and where component tests fit in- A mental model for thinking about the inputs and outputs of the components you test- Options for selecting DOM elements to verify and interact with them- The value of mocks and why they shouldn’t be avoided- The challenges with asynchrony in RTL tests and how to handle them
Prerequisites- Familiarity with building applications with React- Basic experience writing automated tests with Jest or another unit testing framework- You do not need any experience with React Testing Library- Machine setup: Node LTS, Yarn

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

React Advanced Conference 2022React Advanced Conference 2022
25 min
A Guide to React Rendering Behavior
React is a library for "rendering" UI from components, but many users find themselves confused about how React rendering actually works. What do terms like "rendering", "reconciliation", "Fibers", and "committing" actually mean? When do renders happen? How does Context affect rendering, and how do libraries like Redux cause updates? In this talk, we'll clear up the confusion and provide a solid foundation for understanding when, why, and how React renders. We'll look at: - What "rendering" actually is - How React queues renders and the standard rendering behavior - How keys and component types are used in rendering - Techniques for optimizing render performance - How context usage affects rendering behavior| - How external libraries tie into React rendering
React Summit Remote Edition 2021React Summit Remote Edition 2021
33 min
Building Better Websites with Remix
Remix is a new web framework from the creators of React Router that helps you build better, faster websites through a solid understanding of web fundamentals. Remix takes care of the heavy lifting like server rendering, code splitting, prefetching, and navigation and leaves you with the fun part: building something awesome!
React Advanced Conference 2022React Advanced Conference 2022
30 min
Using useEffect Effectively
Can useEffect affect your codebase negatively? From fetching data to fighting with imperative APIs, side effects are one of the biggest sources of frustration in web app development. And let’s be honest, putting everything in useEffect hooks doesn’t help much. In this talk, we'll demystify the useEffect hook and get a better understanding of when (and when not) to use it, as well as discover how declarative effects can make effect management more maintainable in even the most complex React apps.
React Summit 2022React Summit 2022
20 min
Routing in React 18 and Beyond
Concurrent React and Server Components are changing the way we think about routing, rendering, and fetching in web applications. Next.js recently shared part of its vision to help developers adopt these new React features and take advantage of the benefits they unlock.In this talk, we’ll explore the past, present and future of routing in front-end applications and discuss how new features in React and Next.js can help us architect more performant and feature-rich applications.
React Advanced Conference 2021React Advanced Conference 2021
27 min
(Easier) Interactive Data Visualization in React
If you’re building a dashboard, analytics platform, or any web app where you need to give your users insight into their data, you need beautiful, custom, interactive data visualizations in your React app. But building visualizations hand with a low-level library like D3 can be a huge headache, involving lots of wheel-reinventing. In this talk, we’ll see how data viz development can get so much easier thanks to tools like Plot, a high-level dataviz library for quick & easy charting, and Observable, a reactive dataviz prototyping environment, both from the creator of D3. Through live coding examples we’ll explore how React refs let us delegate DOM manipulation for our data visualizations, and how Observable’s embedding functionality lets us easily repurpose community-built visualizations for our own data & use cases. By the end of this talk we’ll know how to get a beautiful, customized, interactive data visualization into our apps with a fraction of the time & effort!