Building for Web & Mobile with Expo

Bookmark

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!

You will know:

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

- Configuring React Navigation with URLs

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

- Setting up a custom color theme that supports dark mode

- Configuring favicons/app icons and metadata

- 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/

162 min
27 Oct, 2022

Comments

Sign in or register to post your comment.

AI Generated Video Summary

React Native Web allows for building mobile and web apps with one codebase. The workshop covers setting up navigation, creating screens, and implementing stack and drawer navigators. It also explores platform-specific functionality, responsive design, and deployment options. React Native Web abstracts away complexity and enables developers to do more with less. The workshop provides resources and encourages participation in live streams and community forums for further learning and support.

1. Workshop Introduction

Short description:

Welcome to the workshop! We'll be building for Mobile and Web with Expo through React Advanced London. Download the code repository from codingatwrong.com-workshops-renweb. Pull the latest updates and ask questions on Git Nation Discord or Zoom chat.

Well, cool. Well, welcome again to everybody to the workshop building for Mobile and Web with Expo through React Advanced London. I'm really excited to share this info. It's been fun working with these technologies on a few different open source projects, and we're going to get to go through it together.

I'll say again and maybe a couple of different This is the conference web page here, codingatwwrong.com. I say conference, the workshop, the workshop webpage, codingatwrong.com-workshops-renweb. And you can always see that in the footer of the slides as well. You can go there to download the code repository that we're going to get started with. The whole exercise is written out there so you can follow along if you miss something that I've shown on the screen. And that'll all be available afterwards. The slides are already up there and the conference video, the workshop video, will be available there as well. So check out that web page.

So yeah, if you haven't yet pulled down the code repository and you'd like to code along with me, then please pull it down. There are some recent updates I made, so you can pull the latest if you pulled it down a few days ago. And again, I would encourage if you have questions as we go, you can feel free to unmute ask on the call. The best place would be on Git Nation Discord. That's linked from that web page. You might be in that GIT Nation Discord from the React Advanced Conference. I will try to keep an eye on Zoom chat as we go along and answer questions there. But anyone feel free to ask in audio if I missed a question somewhere.

2. Introduction to React Native Web

Short description:

React Native Web allows you to have one code base that targets three platforms. I've used it to build a real app called Shirley. It's a Focus To Do app. React Native Web puts an abstraction over what's happening on React on the Web, allowing you to target all three runtime environments with one code base. Learn more about React Native Web at their GitHub page. Expo is the recommended way to use React Native Web. We'll be building an Expo app with React Native Web support to target web and mobile.

So React Native web is the name of the technology we're going to be talking about. And it's through Expo. But this is a technology that allows you to have one code base that targets three platforms or more, but specifically three for the sake of this workshop.

So I've used React Native Web to build a real app in the App Store. It's a personal side project. But it's called Shirley. It's a Focus To Do app giving you only what you need to get your to dos done. And I want to show it to you real quick. It's free because I'm not trying to make money off of it. Just trying to have some fun and do some cool stuff.

So if you pull it up, I don't want the emulator there. I want it on my real phone. Yeah, I have stuff up on my screen here in front of this, but you can probably see my phone here. And here's Shirley. When I tap on it, it comes up. I've just got some sample to dos here. But I'm able to tap through it to get two different screens. I can defer to dos a number of days or edit them. And there's a few different screens as far as to dos are organized for available tomorrow and the future and completed and deleted ones.

Yes, I did make the most stereotypical app ever, the to-do list. But I am obsessed with to-do lists and I want them to be exactly the way I want them. And I was able to build them for myself, thanks to React Native Web. And you can see it over here on the left. The same app running in a web browser. So this app that I'm just maintaining on the side, I'm actually maintaining two apps like this on the side. It targets the web and iOS and it could target Android, but I don't have an Android. So I haven't worked through a little bit of a challenge on that side, but it targets all those platforms and it's nice and responsive. You can see that it fits well on a mobile form factor, and it fits well in a browser form factor as well with the sidebar built on the side. And this is the kind of app setup we're going to be building together today so that you have a foundation if you want to build or want to try to build an app with React Native Web and to see if it works for your projects. And registrations are free for surely if you want to go to ShirleyToDo.com, you can sign up for free and use a try out my to do list app. You don't have to charge money when it's so easy to do. You can do this on your side on the side. Yeah, sure. Surely to do come and the code is all open source. So here's a bitly link to get to the source code on GitHub. And the code will look very familiar to you from what we build together today. So overview of what we're going to be doing in the workshop. We're going to talk about what React Native Web is. We're going to walk through and this is going to be by far the bulk of the workshop walk through setting up an app skeleton that's ready for you to add your own functionality to. And then at the end, we'll have a brief discussion. I'll try to remember to make sure we have time for it about when to use React Native Web. I'll share my thoughts and anybody that wants to chime in with your thoughts based on what you've seen or maybe tried in the past, we can discuss together.

I want to talk about Test Double, the company that I work for. I'm actually here. I came to React Advanced London in person and I'm out here in Sheffield, England for a client visit through Test Double, the consultancy that I work for. Just out here helping out a client build some React Web software. We're a consultancy that whose goal is to improve the world's software. And I joined Test Double recently because I love their vision and culture of connecting the clients, understanding them, what is your team like, what is your project like, learning and working together to improve things and solve problems and make things in a good place. If you or someone you know would like help, Test Double would love to talk to you. You can go to Test Double.com or follow them on any social media. It's a great place. I love being here and I'm glad they're supporting me to get a chance to give you this workshop today.

What is React Native Web? I have had to put this in a diagram because it's kind of unintuitive. Even what is React Native is not always very understood if you haven't got a chance to use the technology before. This diagram here, we have a professional app and we want to have a website, an iOS app, and an Android App. If you're using normal, default native technologies, you've got an built with Apple's technologies, like the UI button, and an Android app built with Google's technologies, like the button component or UI view. And then on the Web, maybe you're using React. And so in your React, you write JSX and you write a button, a JSX tag, and that turns into a button element in the DOM, in the Web page. And so we've got our three apps there and React makes Web development really nice and really awesome, but we have got three Client apps to maintain.

A lot of you are probably familiar with the benefits of React Native. How it allows you to build one app that targets both iOS and Android. And so you use React Native-specific abstractions like the Pressable component. And when you implement a Pressable, that turns into a UI button on the iOS side or a button on the Android side. I'm not sure exactly what it is under the hood, but that's some kind of the point is that I don't need to know. I can write a React Web app and a React Native app, and now I only have to build for two platforms. So I get to use the same React paradigms and a lot of the same JavaScript code. It's a bit unfortunate, though, that we still need to build two different things. We've got to build React, and we've got to build React Native. So this is where React Native Web comes in. It allows you to use the same React Native codebase and target the Web as a runtime environment. So that same React Native Pressable component that turns into a UI button on iOS will turn into a button HTML tag on the Web. Again, I'm not totally sure what it is under the hood, but something effectively like that. So at this point you only have one app that you need to write, your React Native app with React Native Web support, and you can target Web browser, iOS, and Android with the same codebase. And that's what we just saw in my to-do list app. So really, it's putting an abstraction over what's happening on React on the Web. Instead of writing the exact HTML tags or DOM elements directly in your JSX, you're using that React Native abstraction. The general concept of some text or a view or a pressable. You're targeting all three of the runtime environments with one code base. So, you can learn more about React Native Web at their GitHub page, and these slides will be available and these links are all on the conference webpage down below. So React Native Web is an open-source project. The maintainer works at Meta now on React JS, I believe. It can be used in any React Native project. So if you have an existing React Native app, you can add React Native Web in. But, the recommended way to use it is through Expo, which is the framework built on top of React Native that allows you to just focus on the JavaScript layer and they handle what's underneath. And so, a little link there for reference to see. So if you want to get started with React Native Web, Expo is the right place to do it. And that's what I've done for my projects, and they've worked really really well for my needs. So that's what we're going to do as we walk through today, building out an Expo app with React Native Web support to target web and mobile. As we go, we're going to handle navigation throughout the app, and URLs so that on the web URLs, or paths, show up correctly. A third party UI component library to get nice cool looking components that work across all the platforms.

3. Setting up Navigation and Dependencies

Short description:

We'll be using Expo as the framework on top of React Native, React Navigation for navigation, and React Native Paper for UI components. Install the dependencies and start the app. Then, set up React Native Web and install the required dependencies. Next, add React Navigation with the drawer and native stack. Finally, wire up navigation for the app by adding the necessary code to the navigation file.

Dark mode support, a custom theme so you get your own custom colors involved, and responsive design to make sure things look natural on small and large viewports. We're going to be using these tools and some others as well.

Expo as the framework on top of React Native, it'll be an expo app, we'll be using React Navigation, which if you've done any React Native at all, it's probably familiar. It's kind of become the de facto, kind of most popular navigation library, and it has great web support. And React Native Paper is their UI component library for implementing material design, look and feel. It's also got great web support, which works out really well.

So we're ready to go to the code. I'm going to get pulled up real quick, but in the meantime, if anybody has any questions, feel free to unmute and ask or to ask in Discord, I've got it up here on my phone. But yeah, let me know if you have any questions, and otherwise, we're going to get started. All right.

So if you go to the page, so here's the page linked down in the, in my slides. I guess I could have stuck it up on the bottom here, but oh, well, hopefully folks got it. Maybe I'm going to put it into Discord real quick. I'll just say... Shop homepage. There, that way folks can get to that easily. All right. So on here, we've got that link to the Discord discussion and the exercise walkthrough. I'm going to go there. And again, this is going to walk through everything we're going to be doing together. And if we get done early, we have time to dig into some other things. That's just so that we can pull up Shirley's code and we can add some other features or field any questions you have. But we've got some typical requirements, instructions so we want to clone down a repo. It's a very basic Expo app. I just went ahead and added in Prettier and eslint because I can't operate with those not being present. And so they're in and ready to go with my own particular preferences for how that goes. And you can install the dependencies in the typical way. I've already done so. And so let's just start up the app. So when we start it up, we can hit i to open it up in the iOS simulator. And again, whether you have iOS or Android running, if you're not on a Mac, iOS simulator will not work but you can pull up Android. And actually, the way Expo works, if you have a physical phone, you can very easily run your JavaScript code on there with minimal build time and things like that. So if we open up the iOS app, we just get this default message, open up AppJS to start working on your app, very nice. And if we say W for web, it says open on web, shows up here in the Expo output, we get a warning. It looks like you're trying to use web support, we don't have the appropriate dependencies, the required dependencies installed. So we're going to install those in just a moment. I do want to put it to y'all, if anybody on the call live right now is wanting to run through this actively as we go, let me know if it's not, if you have any questions or have run into anything, getting it running locally. But at this point, you should be able to have this open up AppJS working on a simulator, emulator or a physical device. So any questions on that front as far as getting it running locally?

My other computer here that I have my notes on keeps going to sleep, and so that's unfortunate. You know, I think maybe I'll just switch back and forth over to this browser over here, I think that'll work best. All right, so we get the instructions here of what we need to do to install the dependencies. Yeah, mpx expo install. It's just these three. So I'm going to stop the server here. And these are basically just not installed with expo out of the box because not everybody is running a web project, but it's pre-configured and ready to go once you add those dependencies in. Oh, it looks like a line break got in the way there. So let me just. Npx expo install effectively does a yarn install, but it makes sure that their versions of dependencies installed match up with the versions that expo needs because it has some things pre-installed. And so in the expo documentation, you'll often see instructions to install things with the expo install command. Speaking of that, as we go, I'm going to be explaining what's happening with these different code snippets that we're using. And with react navigation and react native paper, just to sort of give you context, if you haven't used those before or haven't configured them in this way. So now with those web dependencies installed, we can run yarn start again, get some logging output there, which is nice. We can also hit w to open on the web, and now we've got the same message, open up app JS to start working on your app. And this is also running on mobile. And so there we go. One of the reasons that I'm doing this workshop is once I saw this blank slate, I was like, hey, this is great, this is helpful. I believe it, that is running in both places, but man, how do I get started? And how do I build something that looks and feels natural on mobile and on web, cuz they're kind of different. But luckily, react navigation fits really well in both contexts. So, yeah, let's look on here and get started. And we add react native web. So react navigation is the next thing we're gonna set up to get it working for the drawer sliding from the side and then tapping in kind of going into nested pages. So we have some commands here and we are going to want to stop the server. Just paste them in the latest version of react navigation with the drawer and react navigation native which is the core of it and native stack. The documentation for all these open source libraries is linked at the bottom workshop page. And so if you wanna dig in more you can kind of dig into more there. We're also instructed to do this expo install here to add these other dependencies. And I'm gonna go ahead, there's one bit of Babel configuration. And this call all comes out of the read me's for these tools. These have very high levels of adoption in the React native world. So the read me's and documentation are really good. So we add in this plugin just to get reanimated, which is a transitive dependency working. Reanimated is what provides the animations ability is to let React navigation work and animate so smoothly. Okay, kilowatts asking discord. Any specific dips for handling dependency conflicts in expo. I've used react native init for a long time and recently moved to expo. kilowatts nothing comes to mind specifically about dependency complex. But if you wanna share like an example of some of the kinds of dependency conflicts you've had, maybe that'll jog a memory. maybe somebody else on the call will have ideas. So yeah, please feel free to add more details there in the discord chat. All right, so we have well we can start up the server. Yeah, let's go ahead and start up the server. But this is just adding in the dependencies to now we need to wire up navigation for our app. And this is the biggest chunk of code we're gonna be adding. So I'm gonna be pausing as we go along and explain as we go. And I'm gonna actually type, I'm gonna try that and see if it doesn't feel too tedious. But if it feels too slow, I'll copy and paste over. Cuz I don't wanna keep us here too long. So I like to put the navigation structure for my app in a navigation file. I'm gonna make a source folder because I like that, and then navigation.js.

4. Creating Screens and Navigation

Short description:

We're creating separate screens, home detail, and other routes. These screens don't have anything specific to React Navigation. We're just plopping some simple text elements and pressables onto the screen. When the pressable is pressed, we navigate to the specified screen. On Home Detail, instead of navigating to another screen, we pop off the stack and go back to the previous screen. We also set up another route as another screen in the drawer.

I'm gonna make a source folder because I like that, and then navigation.js. Let's just hide this column. And so let me explain one step at a time. First of all, we're creating just these separate screens, home detail, and other routes. And these screens don't have anything that's specific to React Navigation. Mostly, there is this UseNavigation hook that allows us to have the navigation commands. But other than that, we're just plopping some simple text elements and pressables onto the screen. So let me write the first one and maybe I'll copy and paste the others. Navigation equals useNavigation. Oh, I did import, that's wrong, syntax. All right, so we get our navigation object and then we can return our JSX. There's some text on route and then a pressable. Oh, yeah, React Native on press. And so when this pressable is pressed, we say Navigation, Navigate. Can we go to Home Detail? So that's the name of the screen we're navigating to. Let's save and get some auto-format. That's good. Yeah, and so then on Home Detail, the only difference is instead of navigating down into another screen, we do pop, which is to say pop off the stack and go back to the previous screen we were on. And you'll be able to visualize this once you have it in front of us. And then I set up an other route as well, just as another screen that we can select from the drawer.

5. Creating Stack Navigators

Short description:

To navigate between screens, we create a stack navigator. We have two stack navigators: home and HomeDetail. The stack navigator API provides HomeStack.Navigator and Homestack.screens. The component rendered in the stack is not specifically related to Navigator. The options define the title in the navigation bar. Another stack is created with only one screen for parallel purposes.

Now, OK, so that's the screens themselves. Now we need to wire them up to be able to navigate between them. So we can create a stack navigator. First, I guess, yeah, we have two of those there. If you've used React Navigation, this should be familiar. And if you haven't, then this is some basic introduction.

All right, Create Native Stack Navigator. So the home stack is going to be the set of screens when you choose Home on the sidebar. Just call that home, and then we return. So the way that the API of the Stack Navigator works as we get this HomeStack.Navigator out of it, and then underneath it, we put multiple Homestack.screens. So whatever you name the stack, it would just be dot screen underneath there. Give it a name. That's what you can use to navigate to a component. So what is actually rendered out in there, your component that's not specifically related to Navigator. And then options, and what we're using it for is the title that shows up in the navigation bar at the top.

So I'll just copy the other screen as well, HomeDetail. You see there's nothing about navigating back and forth here, it just makes the screens available with names in there. And so for example, when we say navigate to HomeDetail, this is what defines HomeDetail so React Navigation knows how to get there. Oh no, my formatting is fine. We're going to have another stack here. This stack actually only has one screen, which you probably wouldn't do, but I'm doing that just for parallel so there's two different stacks we can go between.

6. Setting up the Drawer Navigator

Short description:

Create drawer navigator with two screens, home and other. The drawer lets us choose between these two stacks, and the stacks let us go to individual component screens. Export default function navigation. Navigation container needs to not render too often to avoid browser errors.

Now we set up the drawer, which is the navigation we saw on the left-hand side for how to get in between these. Create drawer navigator. So this is a pattern that I ran across after some debugging in this setup of some weird behavior and errors that I was getting. I'll explain why in our next step. But this navigation contents is a component that I define that has our drawer navigator inside it, and we set up two screens under here. This API also has a drawer.screen, and we have home. And the component is the home component that is the home stack. So the drawer lets us choose between these two stacks, and the stacks let us go to individual component screens. We have the same for other. The name is what's actually going to show up in the left-hand sidebar. And now, ESLint is helping telling us we're still not using the navigation contents anywhere, so we need just one more thing. Export, default function, navigation. So this is finally what we're exporting out a file, we return, navigation container, and then in here is the navigation contents. And you can see in this comment that I put in the code snippet the explanation for well, you can't see it because it's not the whole screen. Yeah, so navigation container needs to not render too often, or else Safari and Firefox err on too many history API calls. At least the last time I tried this a few months ago, you know, React Navigation uses this browser API and Safari and Firefox will actually error out and tell you you're calling it too often. And so what I do here by this pattern is this ensures that navigation container doesn't re-render Cause there's no state changes and navigation to cause it. But when we look up into a navigation contents, ultimately we're gonna have a hook in here later in the process that's gonna cause navigation contents to re-render. And so by keeping navigation container out of that, that prevents this browser error. It kind of an esoteric thing, but it's one of the things that I stumbled across while trying to work through getting these React NativeWeb applications working. So that's why that kind of unintuitive arrangement of code.

7. Setting up Navigation and URLs

Short description:

To set up navigation, go to app.js and replace the screen with navigation. Reload the app in Expo and test the navigation on mobile and web. Configure URLs using React Navigation's linking object. Add entries for each screen and specify the corresponding paths. Nest screens if necessary. Set the names for each screen. This will provide a natural URL structure for the app.

So now all we need to do is go into the app.js and use a navigation here. We can actually just replace the screen. We just have navigation rendered at the root of the app and we have a status bar as well. Expo has the API just to configure the color that shows up in the mobile app status bar. So with this, we should be set with our navigation. So let's give it a try. I started my server back up, so I can just reload in Expo. I missed a slide. Nope, I did not. All right, so now we see some navigation in our mobile app here. We have the drawer with home and other, so we can choose between those and we see this other bar at the top. There's actually two title bars, which is kind of unfortunate, but we're gonna address that in just a minute. And we have this go to detail here. Because it's a pressable, by default on React Native pressables aren't styled as anything in particular, but React Native Paper's gonna handle that for us a little bit later. For now, this is clickable. We click in and it navigates in with this nice animation into home detail. We have this automatic back button on the top here that's natural for iOS that's typical to what you see. And you can also tap on back to home route and that brings you back as well. So programmatically you can pop back to the top of the stack. And actually, if you go to the detail and switch over to other, I think it'll keep you where you were. Yep, it keeps you where you were when you go back to home. So that's mobile, let's take a look on the web. I restarted my server and so I need to click open web again to start web pack backup cause it doesn't start up by default. So now we have our screen over here. I'm gonna zoom to 100% just so you can visualize what it looks like, even though the text will be a little small. Maybe I'll zoom it back up in a minute. We can see we have the same drawer showing up with the nice animations. It's very nice. If we go into home and click on go to detail, where we go there and if we click back, we go back. Notice that this stack navigator isn't animated on the web. It's just implementing differently on the platforms for what's performant for that platform. And similarly with the stack, let me, I think this is different. Yeah, so on iOS by default, the drawer will push the contents over to the side. On the web, it does not. It just overlaps it. I think the default on Android is actually slightly different, maybe because of performance or maybe because of platform expectations. But regardless, we have a very similar experience on the two platforms. And by the way, if you are an Android, everything we're doing today, works on Android, I've tested it. I don't have any Android emulator booted up today, but it'll work just fine for you on Android as well. So, these two title bars are very distracting. That looks extremely bad. And so I think that's the next thing we're gonna do. Nope, that's not the next thing we're gonna do. I forgot my plan. Let's go into URLs, and then I'll take a break to ask for any questions. So on the web, you'll notice that whatever screen we're on, our URL is still localhost 19006. That would change when you've deployed it to a server, but the fact that you're still just at the root of the application, regardless, would not change. And so we need to do some configuration of URLs to get that to be natural. You would expect that if you're on others, some kind of URL related to that would work. And if you're on the detail screen, something related to that would work as well. And luckily Rack Navigation supports that very well. A Kilowatt says, which Android emulator do you recommend? Yeah, let me, I'm gonna pull up Android Studio to see. My last professional project using, which did target Android as well as iOS for React Native was last year. And I think we did a few different things. We weren't so concerned on that project with OS, like does it work on Google? Does it work on Samsung? Does it work on all the different possible Android configurations? But we were concerned about screen size. And so we had a Pixel for our kind of main testing thing that had, I think it was a Pixel 3 at the time. And then there were some older Pixel, I think, no, no, it wasn't a Pixel. It was some other brand of phone that has a small form factor. So that the width was smaller because we were doing different break point-based design for that. So yeah, sorry I don't have more detail than that. But for just basic starting out using a Pixel device is gonna be very typical cause they're very popular and they have all the Google APIs available. So one of the Pixels is what I'd recommend. All right, so reminding myself what we're doing. Yeah, we're going in and we're setting the URLs. This is good to have this up on the left here so I can copy and paste as well. So there's a linking object you wanna configure with React Navigation. And I've tended to put this, let me get this chat out of here so it's not distracting me. I want the chat to be visible and I don't need the participant list so much. So you need this linking config. And I put it at the top of my navigation file. A lot of what I'm doing, you can organize in very different ways. This is just an illustration of a way to get these APIs and libraries to play well together. But feel free to organize things to your liking. For the linking, I've put it at the top of the file here. And so you say this config. And then what are the screens? And these are gonna be the top level screens underneath your drawer, which is your top level navigation component. So one is called Home and the other is called Other. So we wanna add an entry for each of those. And then you say, okay, for that screen, what is the corresponding path? So in my case, I kind of liked the home screen actually being at the root path of the web server. So that's kind of nice. Whereas for other, I want that to be a slash other. And then underneath the screen like Home, if it's a stack, you can have other screens nested. So you can nest those under there. Same for screens. Cause even though other just has one screen underneath it, it is still nested. And so you give the names again in names being the name given here or the name given here. So that all screens nested through a react navigation have a name. And that's what this config object uses. So we have home root, home, room, home, detail. And so you can say here actually, hey, you know what I'm under the home stack, the home root screen is kind of at the root of it.

8. Configuring Navigation and Deployment

Short description:

We configure the navigation container to connect to the app and ensure that the URL paths change accordingly. By using the initial route name, we can specify the starting point of the navigation. For deployment, Netlify is recommended for single-page apps on the web, while Expo provides great tooling for iOS and Android. Redirects can be used to serve the same index.html page for different URLs in a single-page app. Next, we will integrate React Native Paper to enhance the app's design with material components.

So I don't want to add anything else to the path there. It can just be the empty screen. But then for home detail, I actually want it to nest two levels deep, let's say home slash detail as though it's underneath the home thing. You'll see it in a second. Whereas with other screens is the other route. And again, we don't, we're already under slash other we don't need to go any deeper. So we could just put an empty string there. So I'm gonna save. And yeah, let's look on the web. And I'll explain how these links. Oh, I didn't hook it up. Anyone's following along on the instructions. So you need to configure this, connect this to the navigation container. So this kind of all lives sort of independent of parallel to your config of the screens. Linking equals linking. And now when we go over here, our home screen is normal place, we go to detail it's now under home slash detail. Sorry for that little bit of small font size in the browser there. You would invite zoom in the address bar doesn't change. And if I go to other we are taken to slash other as well. So this is really great. This is what you'd expect on the web. And this makes a lot of sense.

One thing you'll see, so if you go to other and you reload the page, you'll see your brought back to the other screen. So that's one of the reasons to have these URL paths changing as to if you copy and paste a link or bookmark it, you'll be taken back to where you wanna go. But something interesting happens if you're on a child screen like detail and you reload. So check it out, I'm on the child screen and I've got the back button within the react navigation. But if I reload, it goes away, there's no back button. And if I click back to home route, it doesn't go anywhere. So what's going on here? What's going on is that react navigate, I respect the folks who maintain react navigation so much. This is navigation is a hard problem to figure out any ways let alone having to work consistently on iOS, Android, and web. It is really great that we have this abstraction for us that we can benefit from. So the idea of a stack is not strictly a nested thing. And so, when you say, I wanna go to home slash detail, react navigation says, okay, that's the screen underneath here we're good to go. So that's where you wanna go. And so it's not automatically like programmed in, oh yeah, this is nested under the root. You're just telling it the screen you want it to go to. So the key is that react navigation doesn't see that you were underneath home route and you need to programmatically tell it how to do so. And the way we can do that is with this initial route name. So under the home stack, you can say initial route name, home route. And this means, hey, home route is the start. No matter where you're going, even if you're coming in through a URL, you're starting at home route. So if we save and now we load home slash detail, it says, okay, I'm gonna bring you to home detail but you're nested under the route. So you have the back arrow. You could click it to get back there, you can click home route to get back there. So now we get the functionality we would expect. We don't get orphaned by, and starting out at a URL that is nested further into the application. All right. So with that we have our navigation working. These two navigation, these two title bars still look terrible. So we still need to fix that. But we are able to move around and go where we need to go. So let me just pause for a second before we move on to React Navigation Paper. And I'm gonna keep an eye on the chat as well as an audio. Does anybody have any questions? On whether you're following along and maybe something's not working. Or you're just thinking about it and you have questions about these APIs or how these tools work. And I see a kilowatts with a note, any hints on how to deploy single page app or in a Docker container? Let me answer that briefly and then deployment will be one great topic we can get into if there's extra time at the end of the workshop. So I deploy with Netlify. Netlify probably a lot of folks are familiar with it. It's sort of a hosted platform for deploying single page apps. I'm sure they have like serverless function support as well that's all the rage these days. I'm very old and so I don't use serverless functions just because I haven't learned them. But Netlify gives me a nice one command way to deploy. Let me show you in shortly. I'll just pull up the code here so it's available. And this is all available, open source, you can see it. But in my deploy web command, there's an Expo Command, expo-export-web. And so that does the build like your webpack build to build the static assets. And then I do a little redirects thing, but then I do a netlify deploy, and this pushes it up to Netlify. And I'm good to go. Netlify's free plan works great for me for these side projects. So yeah, for the web, I recommend Netlify. And then on iOS, Expo has some great tooling, and Android as well. I haven't done it on Android, but, you know, React Native, you just get a native app built and then you can submit it to Google and Apple using the normal approaches. Explain the redirects thing. This is a Netlify specific thing. So I'm not gonna get too much detail in here, but we can talk about that offline if you'd like afterwards. So redirects, Netlify, there's this Netlify question. Basically, if you have a single-page app and you're going through the app, these different URL's like home, detail and other, there's no actual HTML page uploaded to Netlify to handle that URL. And so you need a way to tell Netlify, hey, in my app, whatever URL you're at, serve up the same index.html page. And this is a common pattern for a single-page apps. And so this Netlify link, which I will paste into here is a solution for how to do it, but basically you're saying, hey, for any URL, if it's not found, go to index.html, and this will serve up the same page, whatever saved path you go to. So that's general Netlify stuff that would work in anywhere, and if you're deploying to something else, you might have to handle that approach in a different way. Any other questions before we move on? All right. Oh, Brian is typing. Let me give Brian a chance to type it. And Nick's as well. Maybe I'll fill the time a bit while I'm waiting just to say that our next step is going to be pulling in React Native paper to get a nice high level component system using material design. It looks great, and it's going to allow us to have nice looking buttons, and as well as styling the app bar and the, what's it called? Doc? Drawer. The drawer, I always forget. Brian says, what's the code editor you recommend using for React mobile apps? Oh, thank you for the compliment, Brian.

9. Choosing an Editor

Short description:

Visual Studio Code and Sublime Text are both popular editors for software development. Visual Studio Code is well-supported and has excellent TypeScript support. However, Sublime Text is a good alternative if you prefer to avoid big company software. It offers great React and JSX support, as well as LSP support for autocomplete and TypeScript. Sublime Text is native code and can be a good option if you experience performance issues with Visual Studio Code.

I'm glad you're enjoying the workshop so far. Visual Studio Code, honestly, it's probably going to be the best. It's just such well supported. Again, I'm very old, and so I use Sublime Text. It is an editor that's been around for a while. It has great React and JSX support. It actually has LSP, Language Server Protocol support as well. And so that's how I'm getting the autocomplete. And if I hover over stuff, maybe? Yeah, so like, all the autocomplete happens and TypeScript support and things like that. Sublime Text is good for those things. I try to stay away from big company software. Microsoft gets information and analytics on your code and stuff like that. And so there's downsides to Visual Studio Code. Certainly, if you're using TypeScript, you can't do any better than Visual Studio Code. I know IntelliJ's WebStorm is also good for TypeScript support. But if you want to try Sublime Text, it's a good option as well. There's a free trial. And it's not implemented with Electron. It's native code, even though it runs on Windows, Mac, and Linux. And so if on your machine, you have performance issues with Visual Studio Code, Sublime Text could be a good option to check out.

10. Node Versions and React Native Paper

Short description:

Nick shared a funny web app problem that crashed everything. Using Node 16 instead of 18 solved the issue. In Node development, it's important to use the long-term support version for production. Even for local development, it's recommended to use the Node LTS version. Ubuntu and macOS often have outdated versions of Node, making it challenging to find the right tooling. Let's now proceed to React Native paper.

Nick said, I had a funny web app problem which crashed everything. Using Node 16 instead of 18 solved the problem, just in case I'm not the only one sweating. So yeah, that's a great point, Nick. I was very confused by this when I was first getting into Node development because they talk about the current version and then the long-term support version. And in other technologies, current means, yeah, you can use this for production and long-term support is for like the big enterprises that have trouble updating, but in Node, you're warned, do not use the current approach for production, like only use the long-term support version for production use. And it's a bit different in React and React Native development when we're just running Node locally as a build tool, but even in the same way, I ran into a problem at one point with the current version of Node and the fix was, yeah, problems happen in that version, like you probably wanna use the LTS version instead, so that's what I do, and I recommend now is to use the Node LTS version even for local development. And yes, Ubuntu often has really old versions of Node, macOS certainly has really old versions of things available, and so getting up or getting down to just the right version of your tooling can be a challenge. All right, I'll keep an eye out for the messages, but let's move on to React Native paper, and maybe after this one, we may take a five-minute break just in case anybody needs a viral break to get some water or something like that.

11. React Native Paper and Server Restart

Short description:

React Native paper version 5 is in release candidate mode. It's recommended to use release candidate 8. Restart the server after adding a dependency.

All right, I'm tempted to just read my webpage, but I'm not gonna do that. So React Native paper. So this is good timing, in that a new major version of React Native paper, version 5, is in release candidate mode. It's in release candidate version 8, which should either increase your confidence, because it's had a lot of vetting, or maybe decrease your confidence, like, oh, how many more of these are gonna be? But all the release candidates have been very compatible, in my experience. So I recommend that we're gonna use the version 5 release candidate, so that you're as prepared for the future as possible. Because it'll roll over to full version 5 soon, and you'll be good to go. So release candidate 8 is the one. This is a good step to stop and restart the server. In React Native, I've gotten into the habit of always starting and restarting my server when I add a dependency, just in case something is weird. It's not always needed, but I just kinda got into the habit of doing that.

12. Customizing Drawer and Navigation Bar

Short description:

Wrap the app with a paper provider. Customize the look and feel. Style the drawer using React Native Paper. Create a component called custom navigation drawer. Implement the custom drawer using the drawer.item API. Tie the custom drawer into the drawer navigator. Fix the double app bar issue by adding a custom navigation bar using the app bar component from React Native Paper.

All right, yeah. So now we have to wrap our app with a paper provider. So we're gonna go into app, paper provider, Auto-complete doesn't always work. So let's just copy this import over. You know, we always need a provider for libraries like this. So yeah, so paper is now set up. So what are we gonna do? Yeah, so we wanna customize a look and feel. I'm actually going to, oh yeah, let me get web started back up again so we can see web. I should show the failure at some point so you can see if you get the error.

So although the headers at the top are very distracting, let's style the drawer first. This is default styling for React navigation, but we can customize this for React Native Paper. So we have full material design control of our look and feel. So let's create a component. I like to call it custom navigation drawer. I have two React Native web apps, open source apps that are both styled very similarly. So I've like gotten to try a few different ways to organize things and put them around. So yeah, let's export default function, custom navigation drawer. We wanna pull in nav props. At one point, I was doing something different there. Let's stick with what the documentation said, but I don't think I need to actually spread that object. I think I should just take the props object. So first we pull out state and navigation from nav props. These are APIs provided by React Navigation. So if you just check the docs of React Navigation for how to customize the drawer you'll see these. And then navigation prop and navigation object is used many, many places throughout React Navigation stuff. Let's come back to is selected in a second. So first what we're gonna return. And I will just say, again, that all this stuff is in the documentation. I did not do deep research to get these things going. There was a bit of connecting the dots, but you will be able to find this information, not just rely on what I have to say. So drawer content scroll view. This is kind of what's recommended for your drawer to allow to scroll up and down if necessary. I don't know how it differs from a normal scroll view, but I'd rather just use the defaults of the library rather than trying to go off the beaten path. And you pass along the same nav props into it that are passed into your drawer. So inside here, we get state.routes. That's the list of all the routes or all the screens that are available underneath the drawer. So we wanna map through those and we don't wanna do a flat list. This is the scroll view handles it. And if you need a flat list in your apps navigation, you have a lot of navigation going on, so that's maybe not needed. So we take the route and the index and underneath here, now is where we're gonna start to customize it. So we're gonna pull in the drawer from react-native-paper. So react-native-paper has a way to style drawers, whether you're using react-navigation or not, but we're actually gonna use that there's a drawer item and there's some different props in here. So it needs a key just like in any list in React, the route has a key we can use. A label is gonna be the text that's shown and so route.name works well for that. That's the same name that was actually configured here, like this name. So that text will come out and we don't have to repeat that. Accessibility label, I've gone ahead and put these in various places throughout the app. It's helpful for testing, it's helpful for screen reading. And so just in their demo code here, we have that as well that way the route name is read out for accessibility if you're using a screen reader. So now active, visually, how do we tell react-native-paper whether a given item is active? I like to pull any kind of non-trivial logic out of JSX. So I'm gonna put it out here. I'm gonna say, isSelected. This is gonna be a function, but it's just a simple one liner. So if I'm given an index, then I'm gonna say, if the index is equal to state.index. So the state has an index property that lets you know which index is currently selected. And so this just lets us compare it. Yes, I could've inlined this, but I don't know. I just like to pull out little functions. It's the Ruby developer in me. So if the current index is selected, then it will be active. Otherwise, it'll be inactive, which means highlighted. And then on press, we need it to be functional. So we say, navigation.navigate. That's the same API again, navigate to that route name, and then we go there. So we've now implemented the custom drawer, and the custom part of it was this drawer.item that's actually used for the display using a material design React Native Paper API for the display. Now, we need to tie it in, and that comes just into giving a configuration prop here to the drawer navigator. Drawer content equals custom navigation drawer. And with this, we should be set to go. So let's take a look in our mobile app. In the drawer, we have this nice, you might recognize that purple from a React Native Paper or from a material design, the new material design in general. So that looks different and nice and cool. And now on the web, we have the same. It's showing up there as well. So we've got our custom drawer. We're going to customize it further as we go, but let's take this one step at a time and get more material design in place. And incidentally, I recommend this development approach from you're kind of scaffolding out a new app is like building one little thing at a time. Don't try to get your drawer absolutely perfect before you've gotten rid of this terrible, terrible two app bar situation. Like, you know, fix whatever's the lowest hanging fruit at any given point in time. And it tends to be very encouraging as you take these small steps and make progress forward. So now to fix the double app bar issue, we're also gonna put in our custom navigation bar and that's the occasion where we'll be able to remove the duplication there. So let's create a new component for that. Call it custom navigation bar. Guess I'm gonna call these paper navigation bar as well to kind of explain what's going on. But let's continue. Export default function. And I apologize for using up half the screen with my notes here, you know, being out at this client site visit, which is very fun, but I don't have a big monitor here with me to put my cheater notes up on the side. Okay, so for the navigation bar. Again, I'm following APIs from React navigation documentation about what you tend to wanna put in a navigation bar and what is passed into it. So we're gonna return. We want an app bar, which also is provided by React Native Paper.

13. Implementing Custom Navigation Bar

Short description:

React Native Paper provides a high level of abstraction for UI components, allowing you to focus on app functionality. The header checks for a back prop and renders the appropriate icon. The app bar content and action are customizable. The navigation bar is hooked up to each stack navigator. The drawer's own header is configured not to show. The custom navigation bar handles it. The top bar and drawer function as expected on both mobile and web platforms. The custom material design drawer and top bar are implemented. Next, we move on to dark mode.

It's not surprising that you have the concept of an app bar as a part of that. And so we have an app bar header and reactative paper in particular, I found has a great high level of abstraction. Pretty much everything I need, even some things that aren't actually in the material design spec, React Native Paper has it available. This can be great for professional projects of any kind, but if you have a side project or a personal project or like an internal system for a company, especially for those, it's like you don't need to redesign the wheel when it comes to reinvent the wheel, when it comes to UI. Using a high level, high leverage component library like paper means you can focus on the functionality of your app. And again, just kind of allow you to be very productive.

So the first thing that we do here in the header is we check if there is a back prop. That will be truthy if you are navigated underneath and you need to go back, and it'll be falsy if you're at the root level screen and there's no going back to be done. So if back, then we're gonna say, app bar dot back action onPress equals a navigation dot go back. So that's a function that will be executed there. And again, that's the same navigation API. Actually, I'm not sure why I use go back there instead of pop. That's interesting. I'll have to look into that offline and see if there's any difference there. Apparently that works well enough because it is not broken for me as a part of my two applications. Also again, an accessibility label so that it reads out as back on a screen reader. And if back is not present, we just render null here because we don't need that icon.

Next we have app bar content. So that's text content, specifically formatted to show up well in the app bar. And options.title. So you remember back in navigation, yeah, we have here. Or for these screens, we gave it a title option. And this might be different than the name because the name is potentially kind of an internal thing. So we get the options title. And again, we're not hard-coding our app bar or navigation bar from anything. We're just taking the configuration from React navigation itself. And then finally, we have app bar action to have sort of an action button. The icon we use is the menu. Good old hamburger menu icon. Accessibility label menu, and then onPress navigation toggle drawer. So when you're using React navigation drawers, that's toggle drawer is a function and method that's made available to you to be able to toggle it. So that'll allow us to toggle it in and out to be able to see the drawer because again, we're reimplementing the navigation bar. We need that to put that in ourselves if we're using it. But we're using React native paper styling for all these things. So next, we wanna hook it up. We need to hook it up to each of the stacks because our home stack and our other stack on those two different screens are separate stack navigators. And if you don't like the duplication, like you could make a function to kind of abstract over that but for the sake of the demo and you can have my own applications, putting it in two places is no problem. So for the Stack Navigator, we say screen options. Once again, these APIs are all documented well. It's easy to find them in React navigation docs. And for the header, we say custom navigation bar. And then we'll just copy and paste this down to our other stack navigator. And I think we're ready. Oh yeah, here's the last step. We configure the drawer's own header not to show since our custom navigation bar handles it. So each of our stacks has a navigation bar. We don't need the drawer to have a navigation bar as well. So we can say, oh here it is. Yeah, drawer navigator, screen options, header, header shown, false. All right, so with this, we should be ready to take a look at our navigation. It refreshes and one of the, a React Native Core team member that I talked to recently at a conference was like, hey you don't need to refresh it yourself, it should auto-reload. So I'm gonna trust him and I'm gonna try to discipline myself not to reload manually all the time because it's probably set and ready to go. And we do see that the top bar looks nice now, it's one instead of two, so that's nice. We have our little menu thing on the right hand side here that pulls out the drawer. And if we're on a detail page, now we have a left button, a back button. And you may remember that the arrow had a little middle part before, but this is the material design styling, at least on iOS. So we're kinda following the standards there. Home, other. Let's check it on the web. Alright, we have the home bar as well. Notice by the way, that the home, the text is aligned to the left rather than the center. And so, I don't remember if this is React Navigation or Material Design, but one way or the other, the styling is made appropriate for the platform that you're on. So, centering on iOS is natural. Putting it on the left, on the web, is more natural, maybe partially because of the size. And so, these libraries will make these decisions for you so that you're getting a more native experience on each of your different platforms. It's not exactly identical, but it's functionally identical. So when we go under go to detail, we get our back arrow again. Oh, and on the web, we are actually using this arrow here. That is intentional, because I know it is going through the same component, so I'm not aware of the reasoning as to why, but that is what they did. So, yeah, our custom navigation bar is showing up, and we're going to be theming that, maybe as the next step, maybe a little bit later, I forget. All right, so now we have our custom material design drawer, our custom material design top bar, app bar. Next, what we have is dark mode. And this will be pretty quick to do. So let's go ahead through this. Let's think about sequencing to see. Theme color. Yeah, responsive design will be a good break point. So let's go through dark mode, and then we'll take a break if folks want a bit of a bio break or just stretch your legs. Dark mode. So let's take a look at what we have for dark mode. On your phone, you probably know how to turn our dark mode on and off. If you haven't seen the iOS simulator, it's actually somewhere different. It's actually under developer, dark appearance. Dark appearance. I don't know why they put it somewhere different. I don't have an Android phone, and so I don't actually know where dark mode is on Android, but you can find that out for yourself if you have Android. Maybe their emulator is more realistic. But when we switch to dark appearance, nothing actually changes on the web. I mean, on mobile. That's interesting.

14. Implementing Dark Mode Styling

Short description:

Let's switch to dark mode on the web and fix the app bar and background. Use the screen background component to switch the background color based on the theme. Style the view with the background color and flex property. Apply the screen background to all screens in the navigation. Import text from React Native Paper to support dark mode for text. Style the drawer with a dark background using the scrollview style.

Let's take a look at the web. We're going to switch over to dark mode. And so on the web, our app bar at the top actually changes to dark. Our drawer does not, the main content body here does not, but the top bar does. So let's fix this one bit at a time. The first thing we need to fix is that XSPO by default doesn't allow switching mobile apps to dark mode. It's interesting that that doesn't automatically apply to the web. So don't assume that things are identical on the web if you're using React Native Web. But we can turn that on. We say user interface style automatic. Save. And we just need, this time we do need to reload the app on mobile. So let's do it. And now we see that the app bar at the top shows up dark. And we can see it actually switching back and forth. We turn dark mode back off, goes back to light. Turn it back on. Goes back to dark. So now we have a parallel experience on web and on mobile. Next, the background. So this large white background, this doesn't look very dark mode. My eyes are still being blinded by the giant white background screen there. So we need to implement a component that's just a screened background that will switch for dark mode. So I called this screen background in my code base. And I tried to make these lightweight components that were reusable in different places so that I didn't need to think about these low-level concerns, except for in one place. So in this component, I don't think we use it here, but I did accept a style in. It's a good idea when you're using a very reusable component in React Native to give it a style prop so that people can pass in customizing styles. And we do need children for sure, because we're always gonna have children for this. So we're gonna get the theme from React Native paper, and then we're gonna say base style. Flex one, which, if you haven't used React Native's flexbox-based layout, this basically means the screen will fill all the available spacing. And then the background color, I'm gonna put this on multiple lines, that'll work better for here, unless prettier formats than otherwise. Background color is theme.colors.background. Another note, if you're a React web developer, and this is your first experience with React Native, CSS doesn't exist in React Native because it's not a web browser. It's implemented with native components. But is a CSS inspired API, the style objects. And so it's like background color with camel case instead of dashes. And in React Native web, all these React native abstractions are taken and translated back into what is needed for the web layer. And so you write it once in React native APIs and you're good to go. So when we get the theme object from React native paper, colors.background says, give me the right background color to use. And that includes light mode, dark mode changes so that you'll get a different theme and updated theme if you switch your phone from light mode to dark mode or back. And then from here, we can just style a view. So it's just a plain old view which is React natives container class. And here I say based style. And then in case anybody does pass in any other styles, we put them in there, render out the children and then we close the view. So just this background color is really the main thing that's needed. Although we do need the flex one to fill all the available space. So now that we have the screen background, let's use it all throughout navigation. I'm just gonna put it around all these screens. In a real React native application, I wouldn't have all the screens embedded in the navigation file. Those would definitely be separate files, but I just put them here for convenience because this is just a sample application. This way when we make overarching changes like this, it's kind of all in one place. So I'm wrapping all these components in screen backgrounds. Again, you could remove this duplication in your app in some kinda lightweight way if you wanted to. We got that import. So let's check and see. So now the screen all looks dark, this dark gray, same on the web. The text is black on dark gray. I don't think that meets accessibility standards. I can barely see it on my screen right here. So clearly that needs to change as well, like ideally. I mean, in the styling with dark mode is we'd have light text on the dark background. Thankfully, that's actually extremely easy to implement because all we need to do is just import text from React Native Paper instead of importing it from React Native. You might wonder, well, why do I need text from React Native Paper? Well, dark mode support is one reason why. So when I save, actually notice that the web page automatically reloaded there. We got our light text there. Mobile app did as well, a light text. And we can see it switch back and forth just to make sure that we haven't broken anything in light mode. Yeah. Black on white, and then white on dark gray. And let's just switch our macOS as well. Light and dark, and it looks good in both cases. Right, now the last thing we need to style for dark mode is the drawer. We again have a blinding white drawer, which if that's your design sensibility, that's very interesting. I have no sense of design. That's why I rely on React Native Paper. But they would say, hey, you know, that should probably be a dark background. So we can style our custom navigation drawer to match that. So let's pull that in. We need use theme again from React Native Paper to get our current theme. And then the API that's made available on the drawer content scroll view is this. Well, you can just style it directly. And so we're gonna use a scrollview style here. We need to do this inside the component because we're getting that theme in by calling that hook. That's what's gonna cause it to re-render if our light mode or dark mode changes. And again, theme colors.background. So style equals scrollview style. Save and let's see what we got. All right, now we have... And this is actually interesting. I was wondering for just a second why we see a lighter gray here and a darker gray here.

15. Implementing Dark Mode

Short description:

Our app now looks good in dark mode. Adding dark mode support is not challenging, but it's just another thing you have to do. React Native Paper provides dark mode support out of the box. You don't need to use React Navigation or React Native Paper to use React Native Web. You can use other UI libraries. This is just one example stack of a way you can get a great app working on React Native Web.

But if you notice, I don't know if you can see it on the video feed, but this part a dark gray overlay appears on the right-hand side. And so the main body of the app actually darkens when the side slides out. This looks like this didn't get the refresh, actually. Let's refresh and see on mobile. Yeah, so I don't know if you can tell, but this gets darker. This is much closer to black over here because it's just a darkening overlay on top of it. But yeah, our drawer now looks good. We've got a nice dark mode support. It's very gray right now. This dark mode mode is not very colorful, but we'll see when we adjust the theming later how to adjust that a little bit. But our app now looks good in dark mode. And honestly, this is already better off than most of the apps that I've built just on the web because adding in dark mode support is, it's not challenging, but it's just another thing you have to do. But the fact that it's in React Native Paper out of the box, really nice. I don't work for Call Stack, the maintainers of React Native Paper, but I'm so thankful that they do this. And so I'm happy to plug their stuff. But, and I should make an important note here. You don't need to use React Navigation or React Native Paper to use React Native Web. You can use other libraries as well. There's other great UI libraries on React Native for sure. These are just ones that I know that are high level of abstraction and that do have great web support. So you're not locked in. This is again, just one example stack of a way you can get a great app working on React Native Web.

16. Choosing a Theme Color

Short description:

Let's choose a theme color for React Native Paper. We can either use Material U, which requires customizing multiple colors, or fall back to Material Design Version 2, which allows us to specify just one primary color. For simplicity, we'll use Material Design Version 2 in this workshop.

All right. Oh yeah, good. No theme, theme color. Let's do a theme color, and then that'll be our break. I hope I'm not making you antsy by mentioning the break so much, but I just wanna make sure I don't keep us here for the whole three hours, but we get a little break in between. So this is kind of the standard material design, look, this looks like any other React Native Paper application, which is maybe totally fine for an internal system, but maybe you'd like theming to be different. You know, this is a purple here. Maybe you want your brand's color to show up there, and so we can actually do this. You can choose theming for React Native Paper, but the way it works, we have to get into a bit of a complexity with a few different versions. Let me show you on their pages to sort of describe it. So Material U, Y-O-U, is how it's called. So Material Design is Google's design system for design, for software, and version three of it is also called Material U, and so React Native Paper version five supports this new look and feel. Some of the details like this big rounded corner button, that's part of the new design. So if you're using the 5.0 release candidate of paper, you have Material Design 3. But the older version, Material Design Version 2, is also available as well. So when it comes to theming, if we are using Material U, the latest version, we have to customize a number of different colors. We have to customize this background color, this text color, which you can't see, but is very slightly purple, and some of the other background colors as well. We have to customize all these different things. When we start adding buttons in the screens, customize those colors as well. But if we're willing to use Material Design 2, the slightly older version, things are actually simpler. We can actually just specify one primary color for our theme, and all the other related colors will be derived from it. So that actually makes configuration really easier. So what I'm going to do is, I'm going to actually back our app out to Material Design Version 2. It's a bit of a older look and feel, like, you know, you just get to look more familiar to you from different Google apps you've used over the last few years. But for the sake of theme customization, it's easier. For your own applications, if you want to customize Material Design 3, you totally can, but to give us something quick out of the box, I'm going to make us fall back to Material Design Version 2 and so hopefully what that means will become clearer as we go through the steps.

17. Creating a Custom Theme and Customizing the App

Short description:

We create a custom theme using React Native Paper's Material Design 2 dark theme and Material Design 2 light theme based on the color scheme. The theme can be easily customized by overriding the primary color. The app automatically switches between light mode and dark mode based on the color scheme. Customizing the theme is simple, and it works on both web and mobile platforms. The workshop covers more topics like deployment and native code. This React Native application is ready for you to plug in your logic and screens, making it versatile and useful.

All right, so we want to make a Use Custom Theme. Oh, I don't want that in the components folder. I want it in source. No, it looks like that's the right place. Oh yeah, I actually usually have these other things in a source components folder, but this works out okay. Now feel free to organize your folders however you like. That works out totally fine in this architecture.

Okay, so this is gonna be a hook that is gonna return our own custom theme with all the customizations we need for it. Use Custom Theme. First we're gonna get the color scheme. So Use Color Scheme is built into React Native and then you can see from my nice LSP integration here, a new hook, interesting, accessing the user's preferred color scheme and it returns either the string light or dark and I forget why I have a default value here, maybe it's just being cautious, but regardless, I have a default to light here. So this is what's gonna tell us are we in light mode or dark mode? Then there's two different themes from React Native paper, Material Design 2 dark theme and Material Design 2 light theme and so we're gonna choose one of those to use based on which color scheme we have. The reason for this is if we don't customize the paper theme at all, we get light mode dark mode support automatically but if we want to customize it, if we want to tweak that primary color, we need to handle the switching between light mode and dark mode. So as a first step we're gonna do that then we're gonna add in that theme color. So we say here base theme, if color scheme is equal to dark, then we use MD2 dark theme otherwise use MD2 light theme. We got those imports and then we just return the base theme for now. So again we've just replicated light mode dark mode switching here using the default themes and we are gonna be on material design too.

So now let's hook that up in app. We get the theme and then we just say to the paper provider that's the theme to use. And because of the way hooks work, if the app changes from light mode to dark mode, the return value of use color scheme will change causing this to re-render and that in turn will cause app.js to re-render providing our new theme to there. So let's save and take a look. So this immediately looks very different. This is very purple. This may be what you're used to seeing when you think of material design because this was a look and feel for quite some time. When we open up the sidebar, we have these buttons here with a very light purple behind it. And then the selected item is purple text. And that looks great on the web as well. So this is a material design too with the default color, the default primary color. And so now from this point, customizing the theme is very simple. So you can choose any theme color you like. This is a surely to do apps color scheme color but you can choose any hex color picker like this one to choose your own theme color. So if you're following along, pick a color that you think is awesome and that represents you and you can just pop it in here. But this is mine. And so then when we need to change here is that we're not gonna return the base theme as is, instead, we're gonna create our own theme. We're gonna spread all the base themes, props but then we're gonna override colors. And on colors we're gonna take all the base theme colors but we're gonna override primary. And for the primary color, we're gonna use our theme color. And that's the theme we're gonna return. So yeah, so with Material Design 2, this is the only color we need to override. We don't need to figure out lighter or darker versions of it. So that's why I fell back on Material Design 2 was to get this easy customizability. So let me just pull up the window there so we can save and see it. When I save, we've got green, we've got Shirley to do green across the top in both. And in our sidebar, you see we have light green. Automatically, there's different green tints are applied and we're good to go. And this primary theme color also gives us all we need for dark mode as well. So let's switch over to dark mode. That looks good. It's less colorful. So that's the interesting thing about Material Design 2 is you don't see any green by default on here. You do see it in the sidebar and you'll see it in the buttons as well. But this is the standards for Material Design. And so instead of you having to make the decisions, Google has done it and they've spent more money than you will thinking about the design system. So yeah, we've got our customized color theme and reacting to paper color scheme. It looks good, it's our custom colors. It looks good on web and on mobile. And we've got some navigation going on that let us get around the app. And from this point, we have more to go in the workshop once we reconvene. We're moving pretty quick. And so it does seem like we're gonna have time for some of the other things like deployment we could get into, native code and differences between the different platforms. So we'll work through that together. But yeah, I mean, this is a React native application. And so you could plug in your logic, plug in your screens, your, whatever API technology you use, whatever data layer you use, this is ready for you to plug those things in. And you have a code base that works on web and on mobile and it looks good and it is very useful. So let me pause there. I'm gonna pause for questions again, spoken out loud if you like, or in the chat. I'll answer those and then after the questions are done, we'll take a five minute break and come back. So yes, any questions about what we've worked on or the APIs or what we've been doing together in the last little bit? All right, I don't see any questions right now, but we'll still be available. So let's take just a five minute break. I'm gonna go off video and audio. Feel free to get up and pick up a snack, buy a break, whatever. I mean, as far as round numbers, it's 4.14 now, British summer time. Let's say 4.20, so six minutes from now, we'll come back together and do our next round. Let's do a little bit of choreography, the next one's 4.15 from now, we'll come back together. So I won't start anything else, even if someone asked, feel free to ask questions in the chat in advance, but I'll wait until 4.20 for us to get started answering those questions and then moving on further. I'll keep this. I'll stop the screen share as well, so I can kind of mess around and get some things prepared. So feel free to take a break and we'll see you back at 4.20 in six minutes. See you. All right, hello again, everyone. We are back. Hope you had a good break. Give it one more second for if anybody has any questions they'd like to share before we jump, oh, while you're thinking of if you have any more questions to share, let me share what Nick's shared in the chat. They mentioned that in Chrome DevTools and in Firefox, you can emulate light and dark mode. I had not looked into this before to know about this. So where I see it, I'm in Firefox. Where I see it is in the inspector tab, little moon icon there. I can click on that to toggle dark mode if my computer's in light mode. And I believe if my computer was in dark mode, I could click on this to toggle light mode. So that's very useful for quickly going back and forth and not having to keep settings open.

18. Implementing Responsive Design

Short description:

To create a centered column, we use the max width style property and flexbox approach in React Native. The column wrapper and column components ensure the content is centered and has a maximum width of 640. By wrapping each screen with the center column component, we achieve responsive design that adapts to different screen sizes. The content is centered and fills the full width on narrower screens, while maintaining a maximum width on wider screens. This approach provides a pleasant user experience and optimizes space usage across various screen widths.

So Nick, I appreciate that. Thank you for that tip. If only it was that easy in the iOS simulator, maybe it is in a menu and I don't know about it. Cool any other questions before we move on or feedbacks?

All right, let's go. So responsive design. So that's very important. And to stay an agent has been for many years as far as getting app that looks and works well on small screens, as well as large screens. Expo works on iPads and tablets, just fine as well. So we want a responsive design to take advantage of that. And also for our screen width here, this text is way over in the corner of a wide window. That's even wider if I'm using my full screen. So we would like some responsive design to make things look good for the screen size that we're on. So let's take a look at how we can go about that.

The first thing I do for my apps is to do sort of a centered column. And let me zoom back to 100% so you can see. So this, I mean, yeah, this is all the way over on the left. One typical design thing is to center a column at a certain width, maybe different widths depending on how big the window is, but you center your content to make it easier, easy to get to. So let's see how we can do that. This is actually pretty easy to do with the max width style property. So let's, again, make a nice reusable component, we can use different places, we can call it the center column. And then I took the props here, let's see here, column style children. I don't think column style, we're gonna use as a part of this workshop, but again, I'm taking this code, extracting it of my open source projects, apps that are doing these things. So for this column we want to return a view. Yeah, so actually, let me come back to the views because it's really the styles that we have that are kind of explaining what's needed. Stylesheet.create. And again, if you're new to React Native, this is the API for creating basic stylesheets. We want a column wrapper and a column. And the term wrapper here just means it's something around something else and I don't have a better name to call it. So the column is the inner thing, that's the column of content. We want it to be flex one to fill up the full height of the area we have available. And we want to maximum width on. We don't want it to be any wider than 640. You can pick a different width, but that's what worked out well for my applications. So if the window, the viewport is narrower than that, fine, fill the full width. But if it was wider, max it out at 640, then the column wrapper says, what do we do with that column if it's got a minimum width of 640? So we say that the wrapper also as well, should flex to fill its container area. And we say flex direction row, which probably I could have just kept one of the defaults there, but justify content center. So that's what's saying we're using React Native's flexbox approach to say, this should appear in the center. So it's max out at 640 width and put it right in the middle. I keep showing this as though you aren't aware of what center is. You know what center is. So let's go ahead and do this. So we need one view surrounding this. The column wrapper styles. And the next view inside styles.column. And then if there's any column style passed in, that's used as well. Luckily, the style API in React Native means if you just pass in a null, it's just ignored. And so if that prop isn't provided, it just fails over nicely. Then we render out the children of course. So those are shown. So this is these two wrappers that should center our content. So let's save and then let's put it into place. So back in our navigation again, which in our simplified app is where the screens are. We're just gonna wrap each of these screens with it. And we put the center column inside the screen background because we want the screen background to go to the full size and fill up the full width. And then center column happens to what is inside. So we do the centering there, centering there, and centering there. And I'll just repeat that adage again that you could remove this duplication in your code base. And I'm not doing it here just for simplicity. So we save and let's take a look. Well, it's moved over some, it's hard to tell if it's centered. So let's just add a bunch more content so we can tell that it's centered. We just repeat the word homeroad a bunch of times. Now when it reloads, we see that it's, we got some space on the left, some space on the right. Now when you're working in responsive design on the web, you may have run across this before if you're a web developer. It can be useful. I mean, there's tools like show me a mobile app as well, which is nice. But also if you just want things to be responsive, you can put your developer tools on the right and then it's easy to drag this. And it's a bit more flexible than resizing the window. So we can see here that a narrow widths, I mean the word home root wraps, but a narrow widths, it fills up the full width. But as soon as we get to 640 pixels wide, the wrapping of that word is kind of interesting. I think there's a little bit of an extra space there just because it's so regular. But you know, after 640 pixels, it expands and stays centered so that no matter how wide we get, it's in the middle. And that ends up being a very nice user experience. In currently on our phone here, the width is wider than 640. The width is narrower than 640 and so the content extends and fills the whole width. So we're already at the point where we are using the space well across this much, you know, scaling from very wide to very narrow, we're using the space well.

19. Implementing Responsive Design

Short description:

When it comes to responsive design, buttons can be styled differently on mobile and web. Media queries are commonly used on the web to change styles based on screen width, but they are not built into React Native styling. To handle responsive design in React Native, a library called React Native Style Queries can be used. This library allows for the creation of breakpoints and the application of different styles based on the screen width. By using the style queries API, styles can be defined using an array syntax, with conditions for when styles should be applied. The use of style queries provides a declarative and readable way to define responsive styles. To use style queries in a component, the style queries object is passed as a prop, and the resulting styles object can be applied to the desired element. By using React Native Style Queries, responsive design can be implemented in a clean and efficient manner.

All right, what's next when it comes to responsive design? So more complex situations. So buttons is very common. At least in the design APIs that I use and the design interfaces, you know on mobile, it's very common to have buttons one above the other, very reachable by your thumb. On the web, with a lot of space, it's very common to have buttons next to each other because it's just typical back to 1984 and the Macintosh, if not earlier, you know, buttons next to each other was a very common paradigm.

So how can we reverse them around? So on the web, you typically accomplish this with media queries and the concept of a break point where you just decide, hey, at a certain width, anything can change in my styles and so you set that point, you code for it, I forget the syntax because I haven't done it in a while directly. But you basically say if the screen is, typically you'll say if the screen is bigger than this size, then you add in these additional styles. So media queries like that are not built into React Native styling. And there are a bunch of styling libraries for React Native and I would expect a lot of them do have support for that. But if you wanna take that, then you need to take that whole style library as well. And I wanted an option, I've got material in a design through a React Native paper, I didn't wanna have to add in another styling library just to add in responsive design. So I made a very simple library. This actually came out of, we re-implemented it, but in a client project that we were on, me and my former coworker Ashley Parker, we thought about how to handle responsive design and breakpoints, and we built some things sort of for that project. And then after the project, we rethought it and tried to think about something more scalable, and we put this library out there. It's called React Native Style Queries. And so use whatever you like to handle responsive design, but I wanna show how you can use React Native Style Queries to do it. And the concepts will translate over, but just different libraries may have different APIs. So let's add React Native Style Queries. And next, I found that it's very helpful to have a breakpoints file, just some file that contains your logic for breakpoints. It's easy for these details to leak all the way through the rest of your code, and then it makes it, there's a lot of duplication and it makes it hard to maintain. So, separating out these concerns can be really good. For right now, we just need one value. Breakpoint, just one breakpoint value. I call this one medium and the numbers came out of experimenting on Shirley to see what made sense. So with the 429, actually, I guess I realize that that 650, 640, that could come out of a breakpoint as well. We may update that in the future because we have time to. So, but this breakpoint medium of 429, let me go ahead and do it now. Let's follow my example of what I'm saying here. Notice, I mean, in my example code, I let that duplication leak out into other places. So now not only are we setting the column max width at 640, but that breakpoint is also available for other usages as well. So cool, I updated exercise. I'll have to update this afterwards. All right, so with a breakpoint medium, what can we do? So basically the idea is smaller than 429 is small. 429 to 640 is medium and above 640 is large, and you can add in other breakpoints as you find that it's useful to style different things. So now we can create a button group component that's gonna handle switching the direction of the buttons. Let's do this. As usual, we want children to be able to be passed into there. And let me explain this use style queries here. So style queries is just a conventional name that we use here. Just like with the React Native Style Sheet API, you're given names for different things. Like in this case, button container. I wanna specify some button container styles. But here's the way the React Native Style Queries API works. You pass it an array instead of an object. And so if you pass a plain object as one of the elements in that array, then these are styles that'll be unconditionally applied. So Flex Direction Column. Other things can overwrite it, but it's like, hey, these are the defaults. And with the mobile first philosophy of design, you generally wanna have your defaults be what works for small, what works for mobile. So in small and mobile, we want the buttons to go in a column. So Flex Direction Column will accomplish that. But then we can add other elements to the array that can add in conditions for when things might need to change. And there's some helpful helper methods included with reactive style queries, like screenWidthMin. So when you're calling screenWidthMin, the first value is the minimum pixel value for the screen width. So if we say breakPointMedium, this basically says, if the screen width is at least this width, at least the medium break point width, then add these additional styles and merge them in on top of the previous ones. And so in this case, we say flex direction row. So medium and above, change the buttons to be in a row instead of columns. And then justifyContentFlexEnd, which is align it to, if my face is the app, align it to the right, justify the buttons to the end, because that's been a convention since 1984 with the Macintosh. So this is a nice sort of declarative way to define these responsive styles. And I, I mean, I made this API because I like it and I like how it turned out. I think it's very readable. And because if you're not doing this and if you're coding it by yourself, you have to put conditional logic in your component to modify the styles or merge things in. And it just feels messier. It feels more like the StyleSheet API to be able to declaratively put this out here. So now to use style queries in a component, we say style equal, we use style queries, of course. And so basically the idea here is we pass in a style queries object, which is an object that has, maybe, these arrays with these configurations for different widths. And what we're going to get out is a normal styles object, a styles object that doesn't have the conditions anymore. It's just the styles to apply for the current situation, for the current breakpoints. So then we can say, return, view, style, styles button container. In the typical way that style objects work in React Native. And we did the children. All right, so if my explanation wasn't clear, we'll get to see it in practice in a minute, and I'll show how it works. But we need to go and get some buttons using this first so we can put it into practice. So let's go ahead and do that. Oh, I didn't save the changes to breakpoints. All right, so in home group, we're just gonna put some buttons in here and we're gonna take this occasion to use some React Native paper buttons because they look better and that'll look nice. So we're gonna get our button group. And then in there, we're gonna use a button, import button from paper, mode equals outlined. That kind of works out well. So you have one emphasize button and some other de-emphasize buttons. We're gonna call it second and third, even though they're kind of out of order. And we'll have another button but this one's going to be contained and it's gonna have an on press. So this is our actual functional button we'll do the navigation. Detail. All right, so just here, basically at the point of use, where we'll just to plop in a button group with buttons under it and we don't have to think about the styling at all right here. I guess we will need to in a minute but for now, please take my oversimplification. So let's take a look at how this looks. We have an error. So let's take a look at what's going on. View is not defined. That was just a temporary error from not importing something. It might still be the case.

20. Implementing Responsive Design for Buttons

Short description:

On the web, buttons are displayed next to each other on widescreens, while on mobile, they are displayed top to bottom. React-Native-Style queries allow for real-time responsiveness. To improve the appearance of the buttons, spacing is added between them using style queries.

Oh yeah, it is still the case. You actually have to let autocomplete help you. All right, so here on the web in our widescreen, it's so wide, isn't it? On our widescreen, we see the buttons next to each other, aligned to the right. In mobile, we see them top to bottom. And if the dark mode is distracting to you, let's switch back to light mode. So now they're one above the other, which is more typical for the web. And if, I'm sorry more typical for, column is typical for mobile and for small screens, left to right is typical for larger screens. And in the browser, we can drag it back and forth. And actually at a certain small size, it'll dynamically change and pop down so that it's one above the other, which is also good for narrow web browser windows. If you ever had a web browser window that narrow. So this is one of the nice things about React-Native-Style queries is that you get this logic in real time. It's not just a matter of what happens initially, but you get responsively popping around. We do need a little more refinement though, because the buttons right next to each other don't look good. It would be good to have some spacing in between them, and this'll give us a chance to actually see some more use of style queries. So let's do it.

21. Styling Buttons with Media Queries

Short description:

In the navigation, we add a styling rule for the buttons using style queries. The buttons are spaced out on mobile with a margin top. On larger screens, a margin is added on the left to address the fact that they're next to each other. The styles are hooked up in the home route styles.

All right. So in here again, now in navigation, we're gonna add a little styling rule for these buttons. This could be in a, in my apps, I put this in a shared place cause this was needed for multiple buttons throughout the app. So style queries. Say this is a button, and we say okay, mobile first, what happens on mobile margin top because we want a margin above these others. And so it spaced them out that way, but that's all the margin we need. Then screen width min, a breakpoint medium. This is now another file using that same breakpoint. So that's a reason to configure those breakpoints so that if you ever adjust the width, and I absolutely did that in my apps as I found that different settings were more useful. You can adjust it in one file and it affects everywhere. So what do we do if we're a larger like this? Well, so in that case, we want a margin in between them to the left of them would work out okay. But we don't want that left margin smaller. But it's okay to still have the top margin cause I'll keep the buttons off of the content above it. So always have buttons, have margin on the top, but when it gets wider, add margin on the left to address the fact that they're now next to each other. So let's save and see what we've got. We have nothing because I didn't hook those styles up. So now let's actually hook the styles up. We'll go into home route styles. So now we pull them style queries again. And again, plugging my own library. It doesn't need to get big, I don't make money off of it but the key is like, I liked that my logic is configuration down to the bottom. And with this component that's already long. I liked that I don't have to add conditional logic into here to mess with the styles. It's a nice separation of concerns. And it's already established on the web. This media query separation of concerns.

22. Styling Buttons and Responsive Design

Short description:

We have added spacing to the left of the buttons for better alignment. The buttons no longer extend to the edges, improving the overall design. Responsive design considerations for button margins and alignment were discussed.

All right, so we can put in here style equals styles button. Now it's just gonna apply to all the buttons. Nice and simple. And now we have some spacing to the left of the buttons. Well, the smaller is just above, but here on the spacing is still above the buttons, but it's the left as well. And if we weren't doing this conditionally, we would have extra margin on the left-hand side when it was small like this, and that wouldn't look good. Now, it also doesn't look good that the buttons are going right to the edges. And at that point, you start to think about, well, where do I have the margin? Is it at the very top level of the app or is it somewhere else? I often make a choice there, and then I regret it and I have to move it around because I'm not the best designer in the world. But those things can be done in various different ways. So I didn't want to get into that in the workshop, but we've got this nice responsive design for the buttons that works out well. Let me see if that was all.

23. Implementing Responsive Design for the Drawer

Short description:

Let's implement responsive design for the drawer. On mobile and narrow screens, the drawer pops up from the side. However, on wider screens, we want the drawer to always show on the left-hand side. React Navigation provides a configuration prop for this. We'll use the useBreakpoint hook to determine the current breakpoint based on the screen size. Then, we'll set the drawer type to either 'permanent' or 'back' depending on the breakpoint. The drawer will toggle between permanent and back as the screen size changes. We'll also hide the menu icon on larger screens when the drawer is permanent. This setup provides a great foundation for building a mobile and web app on React Native.

Oh, yeah. So next is the drawer. So let's talk about responsive design for the drawer here. So on mobile, we can click on this button here to get the drawer to pop up from the side, and that works really well. On narrow screens as well. I'll, that's too narrow. I can't dismiss it now. Narrow screens, that works out well. But what about wider screens? When this is wider, I have a lot of space. And so I kind of actually like the drawer to stay there. That would be a good use of space. And in fact, that's what I did on Shirley as I kept the drawer sticky on the side, always shown because we don't need a ton of white space in the drawer collapsing down. So this would be another great responsive feature is to get the drawer to always show on the left-hand side. And React Navigation has a configuration prop to configure the drawer to always show. We want something to be responsive here. We want it to change depending on the screen size we're on. And in fact, it would be nice if it changed as we grew or shrunk our screen there to change it to be permanent or toggleable. So let's go ahead and do that. We're gonna need a lot more breakpoint logic to do that. This breakpoint large is slightly different. So we'll just see how that works out. So what we wanna do here, I also want some breakpoint names. So at this point, what I want is a break, previously we just were using the measurements and those are being passed to styles of various kinds. Now I wanna use breakpoint hook. And this is a breakpoint that's gonna tell me the name of the breakpoint that we're at. And the reason that will be helpful is that will let me choose what to configure the toggle, which can configure the drawer with. I'm not looking for conditional styles to be applied. I'm looking for, I need to choose the value of the prop to be applied to that. The time to put a stop to pass based on these. And so instead of doing logic against a bunch of numbers, it'll be useful to have a hook that just says, just tell me the name of the breakpoint that I'm at. So let's put these in, we'll just define small, medium, large. Just make them constant so we don't forget what they are. And then we want this to use breakpoint function. If you haven't used custom hooks before, this is how easy they are. And it's very easy to put hooks before you can wrap another hook and just add a bit of your own logic. So that's something I love about the hooks API of React Native is how composable it is. So we're gonna get the width out of use window dimensions. This is a react native API and lets us know the dimensions of the screen that we're in the width of the current viewport. And then from here, we can say if width, and I'm just gonna copy and paste this honestly. If width is greater than the large breakpoint, call it large. Otherwise, if it's greater than the medium breakpoint, call it medium, otherwise it's small. So small is a name for anything less than 429. So great, this will let us figure out the current breakpoint and now we can use that in navigation contents. So we can say, const breakpoint equals use breakpoint. So that'll give us the name of the current breakpoint. And then we can say drawer type. So if you look at the React Navigation documentation, there's a drawer type prop for the drawer that lets you configure how it works. And so we can choose, it's just some strings that you choose between. And so we're gonna choose between them here. So if the breakpoint is large, then say it's a permanent drawer. Otherwise it's a back drawer. And I forget what back is, there's several toggle ones and I forget how they work. There was one of them, there was a bug for a while where if you, the library was not handling the changing of the style. And so it actually caused problems, but back it actually worked in. So I'm not totally sure, you could explore that more yourself if you wanted to, but I believe this combination works. So, and for my side projects, that's the level of understanding I'm comfortable with. You don't need to be an expert to, in order to implement these things. I certainly am not. So for the screen options for the drawer navigator, we just give it the drawer type. It is the type that we've set above. This will either be permanent or back depending on the situation. So let's save it and let's take a look. So now we have the drawer and it's always there. Even whether we toggle it, we still have the drawer on the left-hand and that's a good use of space. Cause you can see what the centered column, we already have a little bit of padding on either side here. Then on the mobile phone, which is small, we still have toggling. And in fact, let's see the responsive behavior. So as I narrow the window, it switches to toggle. And as I expand it out, it switches back to permanent. And actually, if you toggle it and then go out, it still works okay. This is something that there was a bug related to it. This is kind of a weird usage of the library, so they make sense that it wasn't handled, but they actually got it fixed in some version of React Navigation. So now even if you toggle that out, it just goes back to, yeah, it's permanently there when you go wider. So this is pretty cool. This is the point when I got this working in my app that I was like, this is really neat. This feels like a great setup and a great foundation to build a mobile app and a web app on top of. It's pretty cool. There is one other minor thing regarding drawer responsiveness, and that's this menu icon. So the way I've set it up, that's what toggles the drawer. And so we don't need that on a larger screen size when the drawer is permanent. So let's go in and add the logic to hide this icon when we're on a larger screen size. This is in custom navigation bar. We're gonna use that same hook, use break point. Now based on that, we're gonna say, show drawer toggle. Should I show the toggle or not? And actually having this variable here, this is actually a very simple boolean comparison, but I like having named variables for Boolean like this in my React code just to give the concept of the name. Instead of embedding some Boolean logic further down, we say, oh, this is how I decide whether to show the drawer toggle or not. And you can see that in one place. And then you just use that variable down below. Just in a pull request, I made a suggestion about this in the last couple of days as a way to give a name to a concept, a little bit of logic. So we should show the drawer toggle if the break point is not equal to large.

24. Platform-Specific Functionality and Deployment

Short description:

In this section, we explore platform-specific functionality, starting with a simple example of a download button for the app store. We discuss how to conditionally render the button based on the platform using the Platform API from React Native. We also examine other cases where platform-specific conditions are necessary, such as displaying different links or buttons depending on the platform. These conditionals help remove any inconsistencies and provide a seamless user experience. The section concludes by highlighting the importance of deployment and offering to cover it in the next part.

So the break point is large, and I guess you could, if you had an extra large, you'd have to change this logic at that point, but then if it's medium or small, we should show the drawer toggle. And now we can just use that variable here, show drawer toggle, and this. And so the result will be, if show drawer toggle is false, that will not show, and apparently it doesn't render out the word false. Sometimes I forget in React and React Native what gets rendered out there. So sometimes you wanna put a null in, but I think in this case, apparently this works and I don't need the null, but I did for the back. So I don't know. I don't know what the back object is, but I do know what show drawer toggle is. I know it's a Boolean because I'm doing a Boolean comparison there. So now let's take a look. So now on the web on a wide screen, our menu icon disappears. It's still visible on mobile. And if I responsively scale down the screen, as soon as the permanent drawer goes away, the icon is there to toggle it. So it's there only when needed and not taking up space or looking broken when it's not needed. So it's pretty cool, the responsive setup. I got very excited. I love the setup of the app that I can use when I have this responsive functionality working. This, for simple things, for things that you don't need it to look and feel differently than React Native Paper defaults, this gives you a great foundation to build this functionality on top of. So that's responsive designing. And just to review that real quick, we use a max width for the columns just a very simple way that didn't require any logic to get some responsive behavior. We use React Native style queries in order to conditionally change the flexbox layout of these buttons to get them to align differently on a small screen versus on a bigger screen. And then we saw how we could use breakpoints to even change logic of configuring of this navigation drawer to make it permanent or toggleable in different situations. So, cool.

So, this has actually reached the end of my writeup here, but I do have other things we can go into as far as platform-specific functionality. And so, we can use more of our time. I don't need to shortchange you by ending early or anything like that. And I do think there's time to get into deployment as well because that's another key part of it. It's like, okay, I've got this app, but how do I get it out there? How do I do something with it? So, I can walk you through that as well. First, I will pause. What questions or feedback do you have about responsive design and what we've gotten into together today. All right, I don't see or hear questions. So, let's keep going. Let's talk about platform-specific functionality. So here, I'm actually going to show the Shirley code instead because I don't have a code exercise prepared here to go into, but this will be available on the recording for anybody checking it out. So, let's look at platform-specific functionality. The most simple example I can give in Shirley is a little bit of a code exercise. Let's just do a little code, and the most simple example I can give in Shirley is this download on the app store button. So, this is actually something that I wanted there because I wanted people, if they're using the website, to be able to download on the app store. I'm not sure if it's anyone other than me, but that's okay if not. But it just felt like professional and that I could do it. But on the mobile app, and let me go back to sharing... Let me go back to sharing on my actual phone because I'm actually signed into Shirley and I have it running here. So, in the mobile app, it needs a link to download on the app store because you have the app. Like, mission accomplished, you're good to go. And actually, if I had an Android version, I could potentially put those buttons there as well. So, how do I get this condition working? The way we can do this is an API from React Native called Platform. Platform OS is a field that lets you check the OS you're on. And actually, yeah, let's... Thank you. We've got some definition here for what values it could be. It could be iOS, Android, Windows, or macOS if you're using React Native for desktop, maybe by Microsoft, or web if you're using React Native Web. And so that's what we can check. And so I, again, maybe I'm a little overzealous with my variables and conditionals here. But I decided to make an is web variable here, where I just check if the platform OS is web, and then down below is where I use it. So let's find that. One of the reasons I did that was because I used the negation here. If it is not on the web, oh, no, that's something else, I'm sorry. No, I'm looking at the wrong thing. Okay, let's come back to this screen in just a second. This isn't the navigation. Navigation bar, so I actually added in here, oh, it's the wrong thing. This is what happens when I'm not prepared. So in my custom navigation drawer in Shirley, I check if it's web and then down below I say, if it is on the web, then render out the download on the App Store button. And if it's not on the web, don't render it out. And that's how we get this difference of behavior as a result between the two. On the about screen, I have something similar. So let's look at some other cases where you might think about something like that because things that you can just sort of assume when you're just programming for one platform and may not always apply. And so let's see what conditions I put in here in the about screen. I'm moving around my Zoom controls here all over the place. So I checked if we're on the web and let's find usages of it. So Shirley web, so I actually have a link here to the web version of it when you're not on the web. And so let's compare those because I don't go into the screen very often. Yeah, so check it out. So we have Shirley made by coding it wrong get support, ways to say thanks. And then on mobile only I have a Shirley web button there that I can tap on but I still have privacy policy and source available via GitHub and all this other stuff. Yeah, so another conditional. And yeah, I guess it kind of, I wanted a way to get to the web if you're on mobile but if you're on web, it's kind of weird to have that show up and so you can remove weirdness by putting in these conditionals. Let's see if there's any other. No, that's the only usage in there. I think there might've been ways to say thanks. I might have some other examples as well. This is another example of a platform difference. Thanks screen. Oh yeah, okay, interesting. Okay, this is another good example. I'd forgotten about this one but luckily my instincts serve me well to kind of show this. So on the thanks screen let's look at the IS web condition. So rate or review the app. So if we're not on the web we have rate or review the app as an option and that shows up as the second button right there. So how that works is handle review. There is a store review API from Expostore review.

25. Handling Platform Differences and Secure Storage

Short description:

The share feature allows users to send links or request reviews. The React Native share API is used to implement this feature, with fallbacks for unsupported browsers. On mobile, built-in sharing options are provided, while on the web, users are redirected to the website. The Linking API is used to open URLs. Platform differences can be handled by querying the navigator object and checking for available features. The storage API, specifically Expo secure store, is used to securely store sensitive information on iOS and Android. Storing credentials in a secure way is crucial, as web browsers do not provide a secure equivalent. Local storage is used as a fallback, but it's important to assess its security for individual projects. For larger applications, hosting through Next.js or a server-side application with cookie-based security may be necessary.

And so this allows you to send the user to the app store or request a review from them. Let me see what happens when I tap. I actually haven't done it in a while. No, I think maybe because I'm running like a beta version of the app it doesn't work. Not sure, but believe me that it works. Trust that it works. Interesting, I wonder what's going on here linking open URL? Yeah, I don't remember all the logic behind these conditions but basically the idea was, yeah, you can review, like it doesn't make sense to review on the app store if you're on the web, so hide it in that case. The other thing is share with friends. So check this out. We have share with friends. The button always shows and we have a handle share method there. So what do we do? So there is an is share supported check. And so I say okay, if we're not on web, share here so share here refers to the React Native share API. And so let me go through parts of these booleans in my head. So, if we're on the web, if we're not on the web, share is supported. So that means on iOS or on Android in my logic, apparently share is supported. If we are on the web, we need to check for navigator.share. So I actually found that there were some browsers that the navigator.share API was not present in the browser and it would actually crash if you try to call it. So I've wrapped this all up and basically said, okay, can we share? And this comes out of the share API here. So like, this React Native API uses these things under the hood. So if you tap on the share button, if share is supported, we call share.share. And then otherwise we just open the URL. So it's basically just like, take me to the Shirley app and then you can kind of link it from there. So let me show that in action. So on mobile, I can say, share with friends and then the built-in APIs within iOS for sharing or copying or exporting and stuff like that happens. So that's a nice mobile integration. And so that's not available exactly as is on the web. So instead on the web, we click on share with friends and we're just popped over to the website. Actually I think Safari does have the share API on the web. So I'm gonna try that. So let's just try this. surelytodo.com and you open one password here. See if I got this right. So demo account not being accepted. Um, username. Here we go. Not sure what happened there. OK. So let's see if this has that API working. Ways to say thanks, share with friends. Yeah. So the Web Share API is an API that you can use. And so you get similar integration on mobile to tie into these things. Incidentally, I just forgot the Shirley does work on the web on a mobile device as well. So it's not just for desktop. You can integrate in that way. If you want to check, can I use.com, you can see browser support for the share API. Web, Web Share API. So check it out, it's sort of supported in Chrome. It is supported in Edge. Never seen that before. Supported in Safari and not in Firefox. So that was the handling where it's basically, we say, if we have access to share, call it. And if we don't have access to it, just open the URL. And this is the way linking here to explain that. Linking is a API in React Native that allows you to tell the mobile device to open a URL. And it works on the web as well. If you look at the React Native web documentation, this will cause a URL to be opened. And it opens in a new tab. So this is another example of how to handle platform differences. Is not only might you need to check the platform OS, you also might need to check what features are available by just querying the navigator object and using a query in the API to see if the function is there. And you can do that. But you wanna test these things across all of your platforms, even across multiple browsers. You know, it's interesting because when you're using this share API from React Native, it's not clear what web API is being called under the hood. And so a little bit of digging might be needed to find out what's happening to do a detection like this. I'm not aware if the React Native share API will tell you if it's available or not. Seems like store review can tell you if it's available or not, but the share API does not. So I had to find my own way to check for it. So it's important, you know, when you're addressing multiple browsers and multiple mobile devices through React Native just to check to see how things are supported in various different ways. So that's one way to handle platform differences. But the platform differences are very, very rare across my app. I mean, for a simple utility like app, like this, that's showing things on screen and allowing you to load things and type things in and do validations and form editing and dropdowns and things like that. It's like React Native web is gonna handle a lot of your cases, especially with using libraries like navigation and paper that are gonna handle it very well. There are some other things as far as other APIs that differ. In particular, what is the storage API? Actually, I think I'm using the secure store for that package, Expo secure store. So when it comes to storing secure data, this is something important I wanna call out. I'm not gonna show you my solution because my solution is only appropriate for personal projects. It is not actually the ideal security you'd have if important data or company data was involved. So Expo secure store will use secure storage facilities on iOS or on Android to store sensitive information. So I use that to store the login access token. If you're using mobile apps, if you need to store anything that's like related to credentials, you need to not store that in async storage. It needs to go into a secure storage facility. If you're not using Expo, there's a library called Keystore, I think, a React Native key chain, I think, that we'll use, and the documentation will tell you, on iOS we use this, on Android we use that, but it's very important to store credentials in a secure way. In web browsers, there's not actually a secure way to store credentials, there's not an equivalent. And Expo secure store, very specifically, does not implement anything for the web because it's not secure. I use a fallback in my app using local storage that again is, you need to make your own security assessment. It's very important that I say that I'm not giving security advice here. But a lot of security experts and a lot of organizations would say that local storage in a web browser is not sufficient to store credentials, that it's unsafe, and those can be stolen, that can be big problems. And so if you're using React Native Web for a bigger application, you might need to host it through Next.js, or host it and serve it up through a server side application, so you could use cookies or something like that for security. So that's something where you actually don't get the difference for free very easily between the platforms because of security differences in web browsers.

26. Platform Differences, Storage, and Deployment

Short description:

When it comes to platform differences, secure storage for credentials is not an easy answer. TypeScript is well-supported in React Native, but the speaker doesn't have much experience with it. For non-secure local storage in React Native, async storage is recommended. Expo provides a storage option called async storage, which uses React Native async storage under the hood. As for deployment, Expo provides the command 'expo export web' for building and exporting the app. Testing in React Native Web with Expo is similar to regular React Native testing, and Cypress is a great tool for end-to-end testing on the web. Detox end-to-end testing is more challenging in Expo. Expo export web command is used for deployment, and the output can be deployed to Netlify.

Like, there's not an easy answer for secure storage for credentials. So again, I'm not even gonna, you can see it in the Shirley source code, I put a note right up there, it's like, hey, this is risky, like I don't recommend this for elsewhere, but for a personal side project, it was good enough. So that's another important thing to keep in mind when it comes to platform differences.

I'm gonna pause there and ask, I think deployment would be a next good topic that we could go to, but does anybody have any questions about what we've been talking about about platform differences? Or do you have any other topics related to React Native Web that you'd like to see before we go on to deployment? So I will take a drink of water and give you a chance to ask the question. I see kilowatts typing, so I'm gonna give you a moment and then I'm gonna pull up my notes about deployments in the meantime to be ready to go. This is Shirley, this is Shirley. Okay. Any major differences with TypeScript? So the difference with TypeScript is that I don't use TypeScript. And I had a bone to pick and was very nonconformist and didn't want to for a long time, but now I would like to use it. I was hoping to use it on my current project and we didn't get to yet, so maybe we can convince them. So I haven't done TypeScript a whole lot, and so unfortunately, I can't speak to it very well. I know that React Native has really good TypeScript support, and I know Callstack has really bought into TypeScript. And so in fact, some of their libraries are implemented in TypeScript that alternatives on the web are not in TypeScript. So I can't speak to it directly, but in this ecosystem in general, TypeScript is gonna tend to work pretty well. And I know Xbow supports TypeScript very well as well. Sorry, I don't have any more information than that.

Nick says, do you have any recommendations for local storage data persistence in React Native that doesn't need to be secure? Yeah, let's, async store, let me look up those APIs. If you're using bare React Native apart from Xbow, async store, okay, well, async storage is deprecated, that shows you how long I've been doing this. So community packages, let's just follow the links. Yeah, React Native async storage, I think is the, that's where they spun it out. So this is probably the recommendation for React Native in general. Now let's check the Xbow docs. If you're using Xbow, you want to check and see what they have. I don't want to misrepresent this. So in the past, Xbow, you can only use what was built into Xbow, and you couldn't add any additional native code. Or you needed to say, oh yeah, inject me out of Xbow and put me into regular React Native land where I can use native code. Now in the last few years, Xbow's been making major strides to like break that down. And there's an Xbow config plugin architecture now, which basically, I think it automates like tweaking the native code. And so you can add in, you can use Xbow config plugins or write one that lets you tweet the native setup. And so that means you get to, for basically instead of having an iOS project, an Android project that you have to maintain and upgrade forever, you can have your Xbow project that's just JavaScript. And then at build time, it will tweak whatever native stuff is necessary. So, there are ways to add in any libraries into Xbow apps there, but there are some trade-offs there. And I haven't worked with that approach directly because I've just been using plain Xbow on the side, on the side projects, but it's worth checking out. But when you're using Xbow, either way you wanna check and see what APIs they have built in because there's a lot of good ones. Xbow has, I think they've described themselves as the Ruby on Rails of React Native. People use the term, the Ruby on Rails of in a lot of different ways, but in this case, they mean like let's make it batteries included, let's give you a ton of stuff out of the box to meet a lot of your needs. And so this is a long way to say probably, Xbow has a storage option. So let's check it out and see. Yeah, I see Xbow async storage listed in here. Oh yeah, and check it out. It's actually, it's using React Native async storage under the hood. And so really, this is actually them just documenting, this works with us, it's like pre-installed in the Xbow app and you just need to use Xbow install to install a version of it in your code so that your running JavaScript code knows that it's available and has the right JavaScript code. Yeah, so async storage is what I would recommend for non secure local storage. And there's other options as well on the react native directory had other ones. So if you're doing something like Firebase or Apollo for GraphQL, they might have storage built in, in other ways. But as a default, if you don't have something more specific, async storage is how I would go.

Cool, so let's talk about deployment. I see web and then iOS in the order here. So I'm just gonna go in that order. And I'm not an ex, this is an area, the building here is an area that has evolved even over the year or year and a half that I've had these Expo apps. But I can show you the latest I know about us now. So Expo has a command. Expo export web. And now we can come back to what Killawass was asking before about the redirects. I can get into that in a little bit more detail. And I am gonna save a few minutes at the end for the last phase of the slides, which is recap on like, when would I recommend this? So we'll come back to that. Incidentally, I see Testing here. I'm a big, big fan of Testing. I talk about React Native Testing a lot. I'm over not getting into Testing today. I have a workshop tomorrow actually. And so if you're here live, you may still be able to join that workshop. I'm not sure how workshop registration works with React Advanced. But I'm gonna be covering React Native Testing there. But the good news is Testing in React Native Web with Expo is just normal React Native Testing. We use our React Native Testing library, which has the very similar to React testing library. You can use Cypress. So if you are targeting the web, this is one of the tricks. Cypress is a really, really great tool. And the web is very testable for end-to-end testing. And so if you're targeting React Native Web, you can write Cypress tests. And Cypress doesn't care that there's React Native Web under the hood. It just has a running web application and it's able to test. And so that's really great. So I take advantage of that. Detox end-to-end testing is harder in Expo. So that is a challenge. People have done it. I haven't gotten a chance to do it yet. I would really like to have a chance to try, but it's hard and it's not officially supported by Detox. So yeah, that's why for my side projects, I use Cypress for the end-to-end testing. Because if I've end-to-end tested the website, probably that's good enough for my side projects. Anyways, back to deployment. So Expo has a command, expo export web, that will do the webpack build and build out the app. And you can see here, let me just show you the output. I mean, I'll just run it real quick so you can see it. Yarn. Well, let me run it this way because this has, I do the build and then I copy that extra file and then I actually deploy it to Netlify. So let me run mpx expo export web. You'll see it's exporting with webpack.

27. Building and Deploying with React Native Web

Short description:

React Native Web uses Metro as a build tool, but when running through the web, it runs through webpack. React Native Web supports webpack lazy loading and code splitting by default. Bundle size is more important on the web and on mobile. Expo export web is the typical build command. The output is the Webbuild folder, which contains the index HTML file, favicons, manifest JSON, StaticJS chunks, and bundled JavaScript. Deployment options include uploading to S3, Netlify, and other platforms. Next.js can serve up Expo web apps through the ExpoNextAdapter.

So React Native doesn't use webpack for building. It uses Metro, a React Native specific build tool. But when you're running through the web at development time or build time, it runs through webpack. That's part of what React Native Web sets up for you. So this builds out the results, it builds out webpack. We get a recommended size limit issue where the icons are all built in and it's too big, but that's one of the nice things about a side project. Like, I got a side project. I don't care, it loads fast enough for me. And so you can really be lean when you're building just for yourself and when you're making it available for free and not charging you money.

Now, I will say React Native Web does support webpack lazy loading and code splitting in that way by default. And I have a live stream, and one of the topics I'd like to look into soon is just trying out code splitting in React Native Web because probably it just works and that would be really great. So yeah, but for my uses, I haven't done that. But that is a difference between mobile and on web. On mobile, like the users are downloading the whole app and so it's just there and it's just available. Code splitting can affect startup time. I know especially on Android, so that could be a reason. But it's very different where on the web, those things are being downloaded from the server as you use the app. And so bundle size is much more important on the web and on mobile. So there are some interesting things like that that come out when it comes to, even if it's the same app deployed to web and mobile, there are differences there on the considerations you make. But I mean, as far as expo export web is kind of your typical build command, like I just get the output, Webpack is making recommendations. Thank you, Webpack. Maybe I'll heed you someday. But really, it's just all I put into this Webbuild folder. You've got an index file, is very colorful with my syntax highlighting and is kind of minified already. But we just get a bunch of stuff by default. I haven't looked into customizing this too much because it works sufficiently for my side project. You could, of course, overwrite this index on HTML file, if nothing else. But a lot of what goes into here as far as like the app colors and like the icons, favicons and stuff like that, that comes out of app JSON, which is the expo config file, where you can configure the favicon to use. You configure the theme color to use if a user saves that as a PWA to a home screen icon and things like that. So basically, when it comes to those things, you tend to customize that stuff through the app JSON file for Expo. For example, up here, this is the icon that's used for mobile, at least for iOS, and a splash screen image and background color for it and things like that. So you tweak those for Expo and then it exports it in an appropriate way. But yeah, I mean, we have our index HTML file. We have our favicons here. They're very small, 60 pixels. Manifest JSON, which is the web manifest, which is related to progressive web apps. And then, I don't know what PWA is, there's some icons there, apparently. And then there's StaticJS. This is the different chunks of the app that are split out. And you would have more chunks if you did, you know, code splitting and lazy loading in your code, which I would love to try again sometime. Oh, and there's my download on the app store badge, that ping file is included as well. And this is just bundled with Webpack JavaScript. So as far as deployment on the web, once you have this folder, then it's like cool. And you can just like deploy it as you choose. Like you can upload it to S3. I uploaded it to Netlify cause that was just a simple command line interface that you can do, but you're pretty much set to go. And at that point, it's just like a built React app or any other built front end app. One other note that I will say is that if you do use Next.js, you can serve up Expo web apps through Next.js. And let me see if there's notes on this cause I want to point you to it. Looks like I took that out. This is React Native Web. Expo developing for web. Yeah, this link. This link is on the workshop web page there. Developing for web. Publishing websites. So this is the instructions and Expo's notes. I think this would not be in the React Native Web documentation cause the specifics of building is specific to Expo. So, locally. So there's instructions for AWS, Amplify, Vercel, Surge, Netlify, GitHub Pages, Firebase hosting. So a lot of different instructions in here. What was I going in here before? Learn more about Netlify. Choose web build as the path to deploy. I don't even remember what I was about to say. I see Kilowatt says that detox equals headache. I am so torn, Kilowatts. Because I want end-to-end testing to work and detox is good and they've worked very hard. But even I work with an extraordinarily talented tester and he's staffed on a React Native project. And he's like, I can't get the flake totally out of my detox test. I'm like, oh, like, if you can't do it, I don't know if I'll be able to. So detox is a challenge. Absolutely, absolutely. And they're trying to solve a hard problem. So I don't fault them. I cannot make a better end-to-end testing tool for mobile. So yeah, I figured what I was going with that, but yeah, so this web build folder, once it's built here with Expo, you can upload it however you like, and here's some different suggestions. But it is a built file and good to go. Yep, I like Netlify because again, like they say, Netlify deploy, and you're set to push it up there onto the server. And I made that qualification earlier that I'll just point back to as far as this answer here. Let me see if this page will summarize better for me. Yeah, if you're building a single page application with anything, including React Native Web, or an app that manages its own routes, you'll wanna add a redirects file to your published directory with the following line, take advantage of browser history, push state, and there's more information in their docs. So, yeah, I think I was gonna be talking about serving up Expo apps in Next. Next.js, yeah, and using Next.js with Expo for web. So this is helpful to know. Let me read off the page real quick. next.js is a React framework that provides simple page-based routing as well as server-side rendering. So, server-side rendering can be great for performance. If you're like, yeah, I wanna build with React Native Web, but I don't want to just have to be client-side code that's downloaded. I want it to be able to be rendered on the server as well. Well, there's integrations, there's an ExpoNextAdapter that will help with that.

28. Building for Native with EAS Build

Short description:

Next.js does not provide server-side rendering for Native apps. EAS Build allows you to compile and sign Android and iOS apps in the cloud. It is a paid service, but there are open-source plans available. EAS Build local allows you to build the application on your local computer. It requires Android Studio and Xcode to be installed. The building process may take some time. The paid Expo build service offers faster build times and priority access. JavaScript updates can be deployed over the air in React Native. Expo provides its own method for deploying updates.

This could also be helpful for securely storing login credentials because Next.js runs on the server. So I haven't played around with this, but I would advocate for it. And if you need that server-side functionality, or if your team already has Next.js experience using Next.js for the hosting, yeah. Oh, and a note here. Next.js does not provide server-side rendering for Native apps. Right, that would be a very different architecture, and that is in other ecosystems that things like that are happening, not in the React ecosystem.

Kayla says, would the redirect issue go away if you use Next.js or a server-based hosting solution? That's a great question. That might very well go away because Next.js is basically deciding, hey, I've got these URLs, what do I serve up? And so I would imagine Next.js, this is me speculating here at a workshop that you all have come to on things I don't know, it is worth looking at the way Next.js sets up path routing rather than going for a network. And that approach that I showed was Netlify-based anyways. So really, the key is, when I go to any app, any URL within my app, does my hosting serving environment know to start at the React Native web app? That's the key, and that happens differently if you're running just client-side rendering or, you know, using Next.js or something else on the server side. So that's how I would look into that.

Let's pop over, I'm in England, and so little mannerisms are coming in, let's pop over is a thing that I've heard them say. Let's pop over and take a look at building for native. So building for native here, this is, even though we're using React Native web, it happens in the usual expo way, which is, actually they have abstractions over that other than what is built into React Native. So let me see what I am doing here, and then I can point you to other things in their docs. So I'm using EAS build. EAS is something. Expo Application Services, according to the sidebar here. And let me, again, read off the webpage for you at this workshop. Is deeply integrated cloud service for expo and React Native apps from the team behind expo. So this will actually allow you to compile and sign Android and iOS apps in the cloud, including if you have custom native code, whether you do or not. So it's a build server. So this is a server that will run your build for you. So one of the reasons this can be helpful is, for example, maybe you don't have a Mac. Maybe you have a Linux or Windows machine. So you can't run the iOS simulator locally. Running with expo, you're actually able to build iOS apps because you can use the service to build in the cloud. And then you could test, I don't know how you would test, maybe one of those cloud testing services. But at least, maybe someone else in your team or a tester has an iPhone, or maybe you have an iPhone, but you don't have a Mac. And so EAS Build would allow you to build for iOS without actually having a Mac to do the local building on. Now, EAS Build is a paid service to use their servers to do that. I think there are some open-source plans or some cheap intro plans, but as an alternative, and what am I doing? I think it's the EAS Build local is what I'm talking about here. What happens with EAS Build local, and let me try to find it in the documentations. EAS Build local. No, this doesn't look like it. So I'm not sure exactly where this is in the documentation, but this is an option to basically build your application and running on your local computer. So if you do that, to build Android, you need the Android Studio and all the build stuff installed, for iOS, you need to Xcode installed, so you need to be on a Mac, and you're also gonna need to install, it's gonna run, you have to install the CocoaPods that installs iOS dependencies, which then it will need to install those dependencies and the compilation actually happens locally. So your machine's gonna get a little worm for a little while while that happens. And let me actually start that to show you that happening. Why build iOS? Yarn build. Oh, that's in the workshop app, we're gonna go over to Shirley. Yeah. All right, so I mean Yarn installed to make sure I have the latest. So I'm gonna show you what it looks like when you're building the native app locally. Has this a new version of Cypress? This could take a while to install. Let me stop, let me see if it'll let me build. So when I run Yarn build iOS, which runs EAS build local, it's probably going to ask me for some authentication. Yeah, do you want to log into your Apple account? I already know it's not going to show my password on the screen, so I'm not going to be outing myself. That's me. Nope, you're going to see my one time code, but don't worry. This will not be valid for anything anymore afterwards. So, you won't be stealing my identity thankfully. You have to have like an Apple developer account set up. And anytime you're doing React Native and deploying, you're going to need that. So, it's handling the Apple credential stuff, which is crazy security stuff, which is really nice on the web not to have to deal with. I just have this own app, and I just put it on a server. But Expo does handle a lot of that stuff for you, which is really nice. And now the building is starting. You get these very red warnings that are very scary, but everything is fine. And so just don't stress and just give it some time, and it gets built. I think that this stage is actually going to be building JavaScript dependencies, but a little bit later is going to build the native iOS ones as well. And we're going to get a normal Apple built application file out of it, in which case we'll be able to upload it. I'm going to check the questions. In the meantime, Killawatt says, oh, how quickly do you generally find the paid Expo build service? I do not because I have not paid for it. And so I don't know how quick it is. Now in a previous iteration of it, temporarily when they were getting started, it was available for free, I think in some form. And it took just a few minutes. So it was maybe a little faster than building on my local machine because it's a machine that's primed for it and everything like that. Maybe it was the same speed. Now, on the free plan, there was queuing because they have a limited number of servers that make it available for free. Thank you Expo for doing that in the past. And so sometimes I needed to wait a few minutes for a build machine to free up. In the paid plans you have priority. And so they're able to actually allocate machines to make sure you could turn it around quickly. And especially if you're working in a continuous integration type setup where there's a lot of builds happening, you can work with them to make sure that there are some amount of machines available. If you're a very big enterprise, of course, you're a Shopify or something like that. You might want your own CI build infrastructure instead, but because you have EAS build local, you could run that building on your own servers as well. But that's about how fast the free plan was when I used it. Yeah, so this little slow, as you can tell I set these things up and then I go get a coffee while I'm waiting. So yeah, this is not as quick to push up as the web pack build is for the web. That's just part of things. As a note, I will remind everyone that in React Native in general, there are ways to have JavaScript updates deployed over the air and Expo has their own particular way of doing that. So that's something that's available in the React Native ecosystem. And that certainly applies here as well. In a sense is very similar. Like you're updating, you're React Native web app in Expo. Only JavaScript has changed. So you ship up the new JavaScript for the web and you ship up the new JavaScript for mobile as well. And then users will get those updates. I haven't worked with that in Expo before just cause it's not too needed for my side projects and my professional projects haven't used Expo and haven't warranted that.

29. Using React Native Web

Short description:

React Native web can be used if you need both a web and a mobile app. It's not recommended if you only need a web app or if a mobile app is sufficient without the web counterpart. Additionally, React Native web requires maintenance as updates may break dependencies and not all dependencies work on the web. It is suitable for cases where the mobile and web apps have similar functionalities and user experiences.

But let me check out the docs just so you can see that. I don't see it here so let's just search. Expo over the air, I know they have a service for doing this. Over the air updates. Expo updates, that's from 2020 so that seems like that might be it. Expo updates, a protocol for delivering updates to Expo apps running on multiple platforms. Okay that looks very technical. So it's probably somewhere else in the docs that you can do that. But yeah, so that's something to think about if that's a benefit to your organization and if you're deploying the same app to the web as to mobile probably most of your functionality does work in JavaScript and could actually be delivered. All right so yeah, check it out. So we got C++ going on here. We're packaging things, CPP files, CXX react. So yeah, the local, the native building is happening right now. And so that's why, I mean I guess C++ could go anywhere but this is, yeah, here we go. UI view plus react dot M that's objective C code. That's apple specific and so you're gonna need that Xcode tooling to build that locally. But once that's done and I'll just let this run in the background so we can, if anyone has a question later about it but Transporter is an application by Apple and you can just drag your apps into it. When you're doing Xcode based development there's a different way to do it and you can maybe build, I don't know how. Yeah, that probably wouldn't happen. Typically with expo if you're building it locally you're gonna get a build file coming out of it. I don't have any examples here. Maybe I have one under Firehose. Yeah so here's an example. I'm sorry it's very small on your screen but build and then like some kind of ID there.ipa. An IPA file is your locally sourced iOS application that gets built and it's a normal one for Apple but it's also built that way by a Expo. And so you just drag that onto to Transporter and when that's there, it sends it up. This dialog has popped up. We finally gotten to the point of the Expo build process that it is building. It's using Metro to build the JavaScript of my application. And I think we actually may be almost done. So let's just wait for just a second to see this native build happen. And then we can go to the wrap up slides and then I'll be available to hang out longer if folks have additional questions. Stay on target. There we go, build successful. You can find the build artifacts. And so we now have a new... Yeah there it is, build ending in 083.ipa. So that's how we build for iOS. And then we just drag that over here and it gets sent to Apple. And there, I mean, for, oops, I went to the wrong folder. For internal development testing, like to make another build for myself, Apple's very quick to approve things these days. Years ago, it could take them up to a week to approve apps for production. But lately, and the last consultancy I worked at was very heavy on iOS development. And what they said was like, lately, it's a day or two days. Very different than the web when you can push up an update instantly, but it's not too bad to turn things around. And if you have a major outage with your iOS app, I understand you can kind of submit an escalation to Apple. Like, please put me in the priority queue. Put me in the priority queue and they'll do it. So that's how building works. It's two separate builds to build the web assets or build the mobile apps. And, you know, it's another build to build an Android one but it works more similar to the iOS one. And you deploy them in separate ways but then your app is available on these different platforms. I'll wait for just a second while I'm getting my slides pulled back up in case anybody has other questions about deployment or releasing your application. All right, well, let's spend a few minutes and kind of wrap up here. So the next question is when to use React NativeWeb? You know, depending on your band, you may be wondering like, wow, this seems so great if you're an optimist. Like, why use React for the JS anymore when you can do React NativeWeb and you can have it all at once? Or if you're a pessimist, you can say, well, no, a lot of people are not using React NativeWeb. Like there's surely a reason. The answer is somewhere in between. Like there are use cases for React NativeWeb and there are use cases for regular React JS. You know, the regular React targeted for the web or react-dom as you might call it. Naming is a challenge in the React world. So yeah. I throw it to you all actually. If you'd like to, this is my right at the end, the end user engagement question. If anyone has thoughts you'd like to share, share them in the chat. Or again, if anyone wants to now unmute to chime in, what projects do you think might be a good fit for React Native web and what projects might not be a good fit for it. I'd love to hear if you're thinking about your current professional or side projects, if you might consider React Native web for them or not and why. So let me give you just a minute to answer if you would like to, and then I'll share my thoughts. I don't see any typing, so I'm gonna keep going. And I'll look in case you share any thoughts, especially if you have hot takes in response to my views on this. So here's what I'd recommend, and here's what I recommended in consulting conversations with potential clients about these things. You might use React Native web if you need both a web and a mobile app. I mean, that maybe goes without saying. I mean, like, if it's not actually needed, like if you don't actually need a mobile app, if web is just fine, maybe don't take on the extra complexity and the extra layers that you have to work through. And on the flip side, maybe mobile app is all you need and all your users are gonna be using it through it and it requires a phone, doing React Native in the normal way is gonna require less slowdown and less hoops to jump through than having React Native web in the mix as well. Again, it's recommended to use for expo, but if you're on React Native on the CLI, it's gonna be some work to get React Native web set up. And it's not work you should do if you don't actually need a web app. And if you get a free web app from React Native web, it's like free as in puppy, like you need to maintain it. Like when things update, they may break. Some of your dependencies may not work on the web. So certainly don't look into React Native web unless you need both a web and a mobile app. I see one answer. Oh, yeah, that's a bit unrelated to this question. So I'll come back to that question in just a second and please jump in the chat if I forget. Number two, use React Native web if it's largely the same app on mobile and web. So some organizations, the mobile app is for end users and the web app is for people that work for the company. A consulting app I was in built back in 2015 was this way. It was an app for folks in a hospital, the app, mobile app, Native app was for patients and their families and the web app was for hospital administrators. And the needs, as you might imagine were very different. Like the users are different, what is exposed or what is not as exposed? All the navigation was completely different.

30. Using React Native Web

Short description:

The UX standards were very different. In some cases, it's better to have two separate applications. For my side projects, React Native Web was a good fit. It allows for some variation between web and mobile. However, if you need fine-grained control of HTML or have high accessibility standards, React for the web may be a better choice. The decision depends on the level of abstraction you're comfortable with and the similarity between your web and mobile apps.

The UX standards were very different. They wanted the mobile app for end users to be very polished. It was okay if what was going to the hospital administrator was a bit rougher because they were professionals using it. And so in that case, I would not recommend React Native Web having two separate applications, maybe some shared Javascript code, client code, but two separate applications to target each differently would be better.

In my case, from my side projects, surely the to-do app and then you saw glimpses of it, Firehose, which is a link saving app. It is exactly the same. Like I want it to be... I mean, you saw a few little conditionals, but I wanted to look and function totally the same in one web and on mobile. So that skews way over towards the side of like, yeah, totally use React Native Web.

I was on a podcast episode with React Native Radio with folks from Infinite Red Consultancy. And Robin on the podcast mentioned that she had worked on React Native Web on a client project and it didn't need to be identical on mobile and on web, she said. You know, you could have conditionals, you could render out a whole, like maybe the layout is totally different on a web and on mobile, and maybe it's a totally separate component by, which you can do. But then the children are the same underneath it, like the contents underneath it is the same. And so from her experience and from React Native, from Infinite Red's experience, there can be some variation, but again, largely like, if mostly everything is different on web and on mobile, you're not getting the benefit of it going together. And the third point that I'll say as far as when to use React Native Web is when you don't need fine grain control of HTML.

Now there are ways to tweak the HTML that's generated, you know, React Native Web, I have not had very heavy accessibility investigations into my side project apps. I did do some because I was having some wrist pain, and so I needed the, I forget if it's called voice control or voice command on iOS, but basically allow me to speak to interact with things on the screen. It was such a great experience for me to gain empathy for folks that need accessible labels on elements, it's not the same as a screen reader, it's kind of the opposite, actually, but I improved the accessibility of my app and I submitted a PR to an open source library, I use a date picker to improve their accessibility labels as well, so I can use it better. Thankfully, my wrists are better now, that was a temporary impairment, but I hope I will be more sensitive to accessibility going forward as a result of that. And so I was able to tweak things in React Native web to improve the accessibility for my needs. But if you have extremely high accessibility standards, or you are for semantic HTML purposes, you say like, I need to control exactly what HTML element is rendered out in every case, you're not going to be able to do that with React Native web and so in that case, programming with React for the web is going to give you the control that you want. So that's something you're actually trading off by operating at the level of abstraction of React Native, and having the targeting of the three platforms underneath for you. That's why I think not every React web app should be React Native web. I think it's for ones where you can, with that level of abstraction is okay. Or maybe you're willing to engage with the React Native web project to help improve their accessibility as a part of your project, or their semantic-ness of their markup as a part of the project. Like that's a way that everybody could benefit from it. So that's the reasons why there's trade-offs. The closer your web and mobile apps are, the more it could be worth it to use all of them in one codebase with React Native web. The more different and divergent they are, or the more you need control. Even to the extreme of if you really need very fine-grained iOS and Android control of exactly what is used under the hood, at some point you're gonna build the native apps instead of React Native, and they're separate. And so there's a similar breakdown there where the times where you wanna use React Native for web versus using React Web separately. So that's what I would say.

31. Redirecting Users to React Native Web App

Short description:

There are technologies in iOS and Android that allow React Native apps to handle specific domains or URLs. If a user visits a web page with the mobile app installed, they can be redirected to the mobile app and sent to the appropriate screen. React Navigation supports deep linking, making it possible to navigate to specific screens within the app. Deep linking can be challenging to add after the fact, so it's beneficial to plan for it from the start. React Native Web organizes the app's navigation hierarchy around URLs, allowing for a consistent experience across web and mobile platforms.

Let me go to Killawatt's question now. Do you know of a neat way to redirect mobile web users to a React Native web app, but use another website for desktop browsers? I know that this is a thing, and I haven't been staffed on a project that's used it, unfortunately. So I haven't gotten to try. But there's technologies for mobile apps, I mean, I think it's a technology in iOS and on Android that React Native apps can take advantage of as well, where you basically say, this app handles this domain, or these URLs, and as a result, like, if you go to the web page there, you'll be, if you have the mobile app installed, you'll be redirected over to the mobile app, and you'll be sent to the right place. That's actually, I'm glad you asked that, Killawatts, because that's another benefit of the linking approach in React navigation, so that it supports deep linking. So when I said, you know, home slash detail was the route for this page. One impact was on the web, in the browser, that's the URL you went to. On mobile, the impact would be, if you set up deep linking correctly, you could set it up so that if the user went to slash home slash detail in the web browser, and they had the native mobile app installed, the native mobile app would pop up, and they would be navigated to that React navigation screen. So React navigation has support for that on mobile, and so that's really cool. And there's a benefit you get. I mean, I've heard from mobile devs that adding in deep linking to an app is very hard to do after the fact, if you haven't planned for it from the start. And one of the nice things about the React native web abstraction is you're organizing your whole app around a consistent navigation hierarchy that maps to URLs, and so is literally the same thing as the code thing running in the browser with that URL that will send you over to the identical screen, or mostly identical screen, in the mobile app if you have it installed. So I haven't done that myself, but that's my understanding about how deep linking in general, and React navigation URLs in particular, work. So, sorry, I don't have specifics to point you to there, but I know it's iOS and Android technologies for that URL mapping that the React native ecosystem takes advantage of.

32. Conclusion and Removing Accidental Complexity

Short description:

Developers often focus on doing more and solving new problems, but I believe in doing more with less. Removing accidental complexity is crucial, and tools like React and React Native help achieve that. React's declarative rendering simplifies UI management, while React Native removes native development complexity. React Native Web further abstracts away complexity, allowing developers to build apps for web and mobile with one codebase. Other libraries like React Navigation and React Native Paper also contribute to removing accidental complexity. The goal is to equip developers to accomplish more with less and solve real problems.

So, conclusion. I want to give a quick conclusion here to talk about these things in the abstract on abstractions, because this is something that I care about a lot. So, a lot of developers and a lot of tech shops have this focus on doing more. It's like, let's solve new problems, let's fix new things, let's accomplish like new, totally things that haven't been imagined before, like what's the newest kind of physical sensor we can put in an iPhone, or the most realistic way we can do virtual reality, or the most innovative way we can do React state management. You can tell from my facial expression how I feel about that area. And like, and some things are genuinely very new, very different paradigm shifting, some things that are like hyper optimizations of things that give new constraints. And there's a lot of benefits to all of those things.

I find that in my approach to development, I tend to focus less on do more, and more about doing more with less. So, I'm motivated to find ways to allow individual developers, side project developers, small teams, maybe teams, internal teams within a company, maybe teams that developers that do backend and frontend, and so frontend isn't their bread and butter, isn't all they do, to equip those folks to be able to accomplish more. Like that's the kind of part of the adoption curve that I get excited about, and the kind of problems that I get excited about solving. And so with those things involved, is involve removing accidental complexity. This is a term, I think it's from Fred Brooks, Fred Brooks, for Fred Brooks books, he is a classic developer on very large early software development projects. He has written really great things that have impacted a lot of theory in software development for decades. And he talks about the idea of essential complexity, and accidental complexity. Essential complexity is like, there's just some complexity to this thing. Like if you are doing cryptography, like it's going to be complex. If you're managing complicated decisions in a business where there's 20 factors that come in to deciding what to do, that's going to be complex. Accidental complexity is things that result from the tooling that we have, the software development that we have. And it's like, oh, it takes 10 steps to do this. It's like, well, in my head, it's just one thing. It's just submitting a form or validating a form. It's like, no, you got to write all these things and cook these things up. And we have layers, and we have, you know, a bunch of low level things in the programming language you have to handle. That's accidental complexity. It's things I have to do, not that relate to solving my problem directly but they just relate to the tooling. This is over simplification. It's just one way to think about things. But the idea is when I can find tools that remove accidental complexity that allow people to focus on. Let me just solve my problem and build the thing or build the user interface especially that I wanna build. That's tools that I'm really drawn to. And I really feel like that on the React Native web, React, that's what drives me to React Native and even more so than React, honestly. Like I like React. Some people love React and think there's no downside. I don't know. Like I like some other things, other frameworks. But React is really helpful for removing the accidental complexity. Declarative rendering, the fact that you don't have to manage changing the states of UIs. If you've ever worked in a older approach that is imperative like that, you know that, and I'm working in some legacy code right now in Yahoo UI, it's imperative. And so the declarative approach to react where you just say, here's what I want the UI to look like. And then the React runtime handles updating the UI. That removes accidental complexity. There was some great talks about React internals at React Advanced this year that talked about how React handles those things under the hood. And it's great that React removes it. I love with React Native that it removes some of the native development complexity and learning, you know, iOS ecosystem, Android ecosystem, different languages, different APIs. Like I love to be able to use the language that I like. I like JavaScript. I would love to learn TypeScript as well, but either one of those, that I can use those, I can use the same React programming paradigm. So even just having to switch between equally good options is accidental complexity. And if you can use the same paradigm, that is a way to stay focused on just solving your problem. And I think React Native web takes removal, accidental complexity one step further. For cases where that abstraction works, for cases where you can specify the app, like just conceptually, it's views, it's texts, it's buttons, it's loading a URL, it's saving data to a server, I feel like React Native web is a really great abstraction to remove those things. And actually the other libraries we hit are a great way to remove accidental complexity as well. React navigation is a great implementation of a navigation paradigms, React Native paper is a great implementation of UI elements that have a great look and are really appealing and intuitive to users. Lots of other UI libraries as well, but React Native is a good one of them and it works. Sorry, React Native paper is a good one of them and it works on the web. So all of these, when you put these things together, you get to the point where I can build these apps in my free time, not everybody can, there's life circumstances as well, but I've got three young kids, my time for development is limited, but I'm able to build and maintain these apps and I'm able to give them away for free, actually. It's pretty cool, I can build an app that meets my needs exactly. That gets me excited and I get excited about equipping individual developer, small team startups, somebody wants to solve a problem better than anybody else ever has before and make a billion dollars doing it, go for it. And I love making tools that will equip them so they don't need to have three development teams in order to target iOS, Android, and the web. So fixing an accidental complexity, allowing people to do more with less is what is really appealing to me about all these things. Maybe React Native Web is a good fit for your current project and use case, maybe it's not. Maybe it's a good fit for something else. Maybe you can build something for an internal team with React Native Web that you couldn't build otherwise if you had to do it in three different technologies. But that's what gets me excited about these technologies. And so, aside from any details, I would just encourage you, if that's not the way you think about software, if the only voices you hear are the voices that are saying hyper-optimize, like build the new thing, stay as close to the metal as possible, think about whether that's solving real problems for your use case, or think about whether that's accidental complexity that you can set aside by using abstractions that help you focus on the business need and solve the problem. Kilowatts talks about any thoughts on Remix. Yeah, actually, that really ties into this topic here. I haven't used Remix myself, but I am interested in several of the technologies around combining the server and the client. I see that Next.js 13 actually came out, and things are still kind of early, but React server components are more baked, they're more available in Next.js 13, and that's the technology I'm excited about as well. So when you're on the website, these are all frameworks that try to address, hey, there is accidental complexity, and we have a server, and we have a separate client, and we have to get them to talk. There's complexity around performant rendering of the client, and the SEO, and all those things. There's complexity around, I got to now write an API layer on the server, and I got to write an API client layer on the client, or I have to use one, like GraphQL, which is great, but now I got to make sure those libraries stay maintained. So that's accidental complexity, and in my understanding, if I'm, because I haven't used Remix or Next professionally, but my understanding, they've removed some of that so that you can render things on the server, which is a lot of benefits, I mean on the server, you can get access to the database directly, so that's nice. You can store secrets on the server, store login credentials on the server, and then you can send things down to the client, and you still have the rich interactivity of React on the front end. So that's new trade offs as far as being able to remove some of this other accidental complexity. One of the things for me that I haven't dug into it so much on the side is, because I have this mobile focus bent, I want to make sure that the things I build, so the simplicity of having React Native Web for my mobile and web client is a big benefit, but then it's like, the mobile client, like that's not gonna run around the server. And so the mobile client still needs a way to talk back to the server. There's another full-stack React-based framework called Blitz.js that I've been watching. And Blitz also takes the approach of let's make it simpler to have things from the server get to the client. And the version 2.0 of Blitz, they're actually looking at adding some of that same simplicity to mobile apps. And so the way they have it is they have compilation that happens such that you write, it's a function that matches a certain signature that they have, but you write a function, that function runs on the server, but then in your source code you import from that file as though you're just importing that function directly in your client code. And it transforms that into a call to the server to get that data back. And so you don't have to write the API layer there either. So that's very cool and exciting to me, not for every single system, REST based APIs, GraphQL based APIs, super great for a lot of systems that are very big or have separate teams, but I love the option for individuals, for small teams, to remove the data layer complexity. And Blitz 2.0, once they kind of get to final 2.0, they're planning on building a way to have that same kind of build transformation to work for native apps, for React native apps as well. So that's something I'm tracking with, I'm very excited about. It could be good for me to contribute to, if I can, at least testing it out, trying it out as a user. Certainly a live stream about it as they made progress in that area. But all these places that are trying to find new points in between, it's a server and a client, or basically the React app being fully on the client side versus the application logic being fully on the server side like older server rendered web applications. Finding points everywhere in between, like I love that that space is being explored because it's gonna be ways to remove accidental complexity and different solutions in there will work better for different teams.

33. Workshop Wrap-up

Short description:

I want to point you one more time to that workshop webpage, whether you're live on the call or whether you're checking this out via recording later, go to CodingAtWrong.com slash workshops slash RNWeb. The exercise, the starting exercise and the finished version of the exercise will be there as well. You can also fork my Shirley app if you want, cause it's open source and strip out all my stuff and put in all your stuff. I also do a weekly live stream Tuesdays on 5pm Eastern Time Zone, US time. So if you want to see more content about react native web my weekly live stream is a great place to do that. I'd love to have you joined there or check out the recordings after the fact because those are on YouTube as well. I will keep an eye on the discord, the Ganesha discord chat for a while. If you have any questions in there and again, my own discord server is a great place to join in as well. But yeah, what questions do all of you have? Sebastian says I'm new to React Native and Expo and this session helped me to better understand both. The React Native docs at reactnative.dev are really excellent and if you go into the guides, this is getting started and they'll walk you through things. If anyone's learning React Native or Expo or any of the pieces here, if I can help with questions, definitely let me know. Well, thanks so much to everyone. I think we can call it there. And again, I'll keep an eye on the discord group, but I appreciate everyone joining. Thank you for the encouragement. I'm glad it was helpful cause I do this cause I want to help folks out. But I'm going to go ahead and sign off. I'll see you all in the Git Nation discord.

But that's what gets me excited about, Remix, Blitz, Redwood and React server components with Next.js. Yeah, and that's the extent of my knowledge about those things. All right, I'm not gonna jump off because I have time for questions, so I'll put it out there, but in a form of wrap up, I want to point you one more time to that workshop webpage, whether you're live on the call or whether you're checking this out via recording later, go to CodingAtWrong.com slash workshops slash RNWeb. And you'll be able to get the slides once the recording video is up. Thank you, GetNation and React Advanced, that video will be linked from there. The exercise, the starting exercise and the finished version of the exercise will be there as well. So if you want to go through all these steps, you can, if you want, just please just give me the final result. Like you can do that. You can also fork my Shirley app if you want, cause it's open source and strip out all my stuff and put in all your stuff. But going through the steps to build, it can be a way to kind of learn it and get familiar. There's also links for different ways to stay in touch with me on there and also to get in touch with Tess Dublin if we could help you in our React Native and React and Web Consulting. So stay in touch. There is a, I have a Discord server of my own as well. And so there's links to that on that page. There's a channel specific to the workshop where we can chat about it. There's React Native and testing channels in there. We'd love to have you join if you like and there's an active community of folks in there. I also do a weekly live stream Tuesdays on 5pm Eastern Time Zone, US time. So most of the time in there I'm working in one of my two web and native expo apps. And so you will see all the same paradigms that we've been going through today and you'll have a leg up over anybody else that just randomly jumps into the stream but I'm refining the testing, adding new features, exploring new things, taking suggestions from audience and just friends and coworkers and client folks and doing it there. So if you want to see more content about react native web my weekly live stream is a great place to do that. I'd love to have you joined there or check out the recordings after the fact because those are on YouTube as well. And the link on the webpage or in the slides we'll take you there. I saw I'm going to go off a screen share for a second because I saw some kind of notification but it seems like it's maybe, I don't know. It doesn't seem like it was in the thread on here. But yeah, what questions do all of you have? Any of you have before we head out? I really appreciate you joining in. I hope it was helpful. I hope the video will be helpful for consulting for folks in the future as well. One thing I forgot to say was if I didn't say it before on this webpage the full contents of the tutorial other than the deployment stuff at the very end that's all written out on there. And so you can see it written out if it would be more helpful to reference it in writing with code snippets rather than in video form or in repo form. But yeah, what questions do you have if any? And double check on discord here on the screen share just in case there is something that came in in a different way. No, that's not that's not to the conference. Kill us. You're very welcome. Thank you for saying thank you for the talk. Thank you for engaging in sharing questions and thoughts and for the others that ask questions as well. I really appreciate it. I think we're just about done. I will keep an eye on the discord, the Ganesha discord chat for a while. If you have any questions in there and again, my own discord server is a great place to join in as well. Nick says thank you as well. Nick you're very welcome. Thank you for your engagement. Oh yeah I see questions in the zoom chat. One was sent as a direct message so I won't share that just in case it wasn't meant to be, but it was a thank you, you're welcome. Sebastian says I'm new to React Native and Expo and this session helped me to better understand both. That's great to hear. I must've missed a slide or something, but I meant to say at the start that this wasn't mainly an introduction to React Native. If you couldn't follow some of the React Native stuff, that's the reason. The React Native docs at reactnative.dev are really excellent and if you go into the guides, this is getting started and they'll walk you through things. So anybody who wants to get up to speed on React Native, that documentation is really great for that. You can even experiment in the browser using some technologies they have to do that. But I love chatting about this stuff. I'm not on Twitter very intentionally, but you can reach me on LinkedIn through that page or that discord server or email me. My email address is on there. But I love talking about React Native and I love talking about React Native Web cause I get so excited about this. It's so cool that that open-source libraries there and that Expo supports it, and I can just build apps just in JavaScript and have cool native running apps. So yeah, if anyone's learning React Native or Expo or any of the pieces here, if I can help with questions, definitely let me know. Please reach out. I'm prioritized time to be able to answer folks and help them out in that way. And if you're in the discord group, there's others involved there who can also chime in as well. Cool. Well, thanks so much to everyone. I think we can call it there. And again, I'll keep an eye on the discord group, but I appreciate everyone joining. Thank you for the encouragement. I'm glad it was helpful cause I do this cause I want to help folks out. And it's been really cool what I've learned with these technologies. But I'm going to go ahead and sign off. I'll see you all in the Git Nation discord.

Watch more workshops on topic

React Advanced Conference 2021React Advanced Conference 2021
132 min
Concurrent Rendering Adventures in React 18
Workshop Free
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
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
Workshop Free
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 Summit 2023React Summit 2023
171 min
React Performance Debugging Masterclass
Workshop Free
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
145 min
Web3 Workshop - Building Your First Dapp
Workshop Free
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
152 min
Designing Effective Tests With React Testing Library
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 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
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 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!


React Summit 2023React Summit 2023
24 min
React Concurrency, Explained
React 18! Concurrent features! You might’ve already tried the new APIs like useTransition, or you might’ve just heard of them. But do you know how React 18 achieves the performance wins it brings with itself? In this talk, let’s peek under the hood of React 18’s performance features: - How React 18 lowers the time your page stays frozen (aka TBT) - What exactly happens in the main thread when you run useTransition() - What’s the catch with the improvements (there’s no free cake!), and why Vue.js and Preact straight refused to ship anything similar