[MUSIC PLAYING] SPEAKER 1: Hello and welcome for Lecture 3 in React Native. So previous lecture we talked about a bunch of different topics; one being classes and how ES6 allows you to write classes. React, we talked about the library by Facebook that allows you to write declarative programming. We talked about what imperative and declarative programming were and how React allows you to write declaratively. We talked about props, which are basically an object that are passed down to elements. We talked about state, which is a management system for allowing you to track state in a class component. We implemented the to do app in React and then we teased at something called React Native. And so this lecture we'll be talking a lot about React Native. React Native is a framework that relies on React Core. And so a lot of the paradigms that apply to React also apply to React Native. And it allows us to build mobile apps using only JavaScript. And so, as the React team like to say when this was released, you can learn once and write everywhere. And so React Native supports iOS and Android, and we'll see later today how we get that going. And so how exactly does this work? How are we allowed to write JavaScript and have it run on mobile devices? So first, the JavaScript is bundled. So, just like in React, what happens are a couple of different steps where your JavaScript is transpilaged so going from ES6, ES7, ES-next, down to ES5 code, and it's also minified. And so throughout the process you go from a bunch of different files all to one big JavaScript bundle. This runs on your phone. There are separate threads for UI layout and JavaScript. And so, as we saw, if we're running JavaScript in the browser and that locks up, then nothing works. But in React Native there are actually separate threads for the UI layout and JavaScript. And these different threads communicate asynchronously through a bridge. And so the JavaScript thread will request UI elements to be shown and then, like I alluded to earlier, the JavaScript thread can be blocked and the UI still works. And so what do I mean by this bridge? And so what ends up happening is there are separate threads. So there's one thread for the UI and there's one thread for JavaScript. And so say we're writing React and we have something like a button that we want to be shown. Basically what happens is there's this bridge which will communicate between these two threads. And so the JavaScript will basically say, hey UI thread I want a view or a button. And then UI will basically say, OK here it is a button. And then if I, as a user, go ahead and press that the UI will actually send over to the JavaScript, oh the button was pressed. And so this bridge here is asynchronous, so if something happens on the JavaScript and the JavaScript is actually clogged and blocking, the UI thread can still do its thing and I'll show you an example of that in a second. And, conversely, when you touch something on the UI the JavaScript doesn't know until the bridge basically says, hey, this button was pressed and the UI can talk to the JavaScript that way. And so let's see some example where we can lock up that JavaScript thread and not have the UI lock up. And so here we are in the Snack, snack.expo.io, and this allows us to run React Native and have it all happen in the browser. And so a few lectures ago we wrote this blocking method that basically locks up the JavaScript thread. So we can go ahead and do that again. So say we have a method called block JavaScript. And what that does is you can say, we're going to block and then do this thing, so while date.now so we can say, cons done is five seconds from now. And we can say, while it has not been that much time just do nothing. And then when that's done we can say, OK we're done. And so down here, let's actually create a scroll view-- we'll see what that is in a second-- and a button. And we actually don't care about any of all that stuff. And so, when this button is clicked, we're going to go ahead and block that JavaScript. All right. So everybody following? So, so far we have a scroll view which is basically just a view that can scroll back and forth. We have a button that says block JavaScript, and when it's clicked, it will run this function that blocks the JavaScript. And so watch what happens when I click this button. Small bug. All right here's a chance. Who can spot the bug? Oh, on press. So on press, it will actually block the JavaScript. And you see how it still is scrolling, but that button is locked up. And then only after five seconds have passed do the logs come through and then the button returns to its normal state. But notice how when it was stuck and locked, when the JavaScript thread was locked, we still had the ability to scroll back and forth. That's because all of the JavaScript is controlled on one thread whereas on the other thread all of the UI elements still worked as intended. And so even though the JavaScript thread was locked up here, it was in this while loop doing nothing, the UI elements were still able to scroll back and forth. And so it's not as big of a deal if you lock up the JavaScript thread in React Native but it's still a big deal because none of your event handlers will fire. So any questions about how React Native works, how these UI and JavaScript threads run separately in the bridge? Great. And so what are some of the differences between React Native and React Web which we've been talking about thus far? So there are differences in base components. So as you saw in my quick example, things like scroll view or capital button do not exist in web. Things like style, the way that you style elements, is slightly different in React Native and you don't actually have browser APIs anymore. So things like CSS, animations, canvas, SVG, things like that don't actually exist in React Native. But there are actually things that have been polyfilled. So polyfilled is a term that people use to mean some methods or functions that might exist in one environment do not necessarily exist in all environments. And by polyfilling these we can actually implement them such that all environments will actually have these. And so fetch is something that's not supported by all browsers, but by polyfilling it you can actually include code that will implement fetch if it doesn't exist already. And so things like fetch timers like set interval or console or console.log, console.warn, and stuff like that have been polyfilled so that they work in React Native as well. And also the way that you handle navigation is slightly different in React Native, and we'll talk about that in a future lecture. And so I said that React Native base components are slightly different. And so what do I mean there? So in React Web we had access to things like div or span or P image, and we can just declare those globally. But in React Native we actually have to import from the React Native library, and we'll see how to do that in a little bit. And so divs no longer exist and what we use instead are Views. So View with a capital V is basically a cross-platform, just blank E-Y slate. So basically the same thing as a div. There's no such thing as span or P anymore and so instead we use this text. And so what's unique in React Native is that all text actually must be wrapped by this text tag. As you saw in this previous example lower case button doesn't exist anymore. Instead, we use capitol Button with a slightly different API. And so from React Web, if you want to attach a handler to that you do on click. Whereas, in React Native, you do on press which was actually the bug in the code earlier. And lastly we have these things called scroll views or lists which don't really exist in web world, but they do exist a lot in React Native, and we'll be talking about those in the future as well. Of course there are many, many other components and, if you want to explore them, the documentation is really good. Cool, so let's actually take that example that we wrote last lecture, the to do app, and actually translate it into React Native. And so I have here this implementation, which is exactly the code that we wrote in the previous lecture. And what we're going to do is copy and paste that into the Snack that we saw earlier and go ahead and translate that into React Native. So this is just the command to copy it and let's actually paste that into here. So of course there's going to be many errors just because this is React Web and we're trying to run this in React Native. And so let's go ahead and try to fix those errors. And so first we see stuff like LI, input, button, and those don't exist in React Native. And so we'll have to first replace those React Web components with React Native ones. And so this rendering does not exist anymore. And so let's first do import some stuff from React Native. And we'll be talking about imports and exports a little bit later, but just bear with me for now. And so some things that we're going to need are stuff like View, we'll need a Button and we'll need text. And we'll need some scrolling views and then maybe some more stuff in a little bit. So first let's work on that quick to do component. And so we have a list item here, instead let's actually use a View. Let's actually get rid of this input for now, and we'll add that in a little bit later. But how are we going to change this lowercase button to React Native? Well first we need to replace it with the capital Button, which is React Natives version of the button. It no longer has an on click property and so instead we'll pass an on press prop and then we don't actually wrap the content any more instead we pass a title prop. And so that button's done. What are we going to do for span? Anyone? AUDIENCE: [INAUDIBLE] SPEAKER 1: Yeah, we'll use a text instead. And now our to do is done. So now let's start looking into this app component. So first let's get rid of this render, which does not exist in React Native, and let's start working our way through this big return function here. So first we have a div. Instead of a div let's go ahead and use a View. And then we have a to do count. So what are we going to use instead of this div? We can't use a View otherwise an error will be thrown because remember the only way that we can include text in React Native is by wrapping it in this text component and same thing with this. All right, we see another button and we've seen a button before, so all we have to do is replace that lowercase b with a capital B, change on click to on press and change the content to be title. And then we're done there. All right, UL, unordered lists. So how might we handle this unordered list in React Native? So lists, ULs and ordered lists don't actually exist in React Native, and the way that we handled those instead are by using the scrolling components because we don't know how long that list is going to get and so we better assume it's going to get pretty long and be able to scroll through them if we needed. And so unordered lists we replace with scroll view and now we have what we were looking for. So all of the React Native components, the React components sorry, we've changed to React Native components and now we have-- Oops, something's breaking still. Prompt is another one of those browser APIs that just does not exist in the React Native world which caused our code to crash. And so rather than using one of these browser APIs let's just replace it with some hard coded text for now, maybe something like to do, number, and then whatever it's ID is. And rather than incrementing ID down there let's actually increment it up here. And so now it works. So we have to do number one, to do number two and you can see how we add those. And so we'll fix the style in the future, but basically does anybody have questions on going from React Web to React Native? What we did there was just replace all the React Web components with the React Native components. And it is almost as easy as command effing and replacing like that. Great. And so how are you going to go about styling those components? So in React Web the way we did that was just by adding a class name and then styling in CSS, but in React Native we don't have this concept of CSS. So the way that React Native handles that is by actually using JavaScript objects for styling and what that gives us is the ability to use dynamic styles. Object keys in these objects are based on CSS properties, so we have stuff like margin top, margin bottom, margin padding. And the layout system that we used is Flexbox and so, if you're familiar with the Flexbox system in web, it's almost exactly the same in React Native. One of the key differences is that rather than defaulting to row we default to laying out things in columns. So, in React Web, we have this concept of pixels or percentages, but in React Native we actually use unit-less numbers for length. Which is good because there are so many different devices that this runs on with different pixel densities that having a unit-less number allows us to abstract that pixel density out. The style prop, so the way that you style a given component is by assigning that JavaScript object to a style prop and it can actually take an array of styles. And so, if you wanted to have a bunch of different class names in React Web you'd just start adding those with a space in between. But in React Native you handled that by passing an array of styles. So let's go ahead and add styles to this app that we have here. So first, let's go ahead and style this view. And so right now, as you see, each to do has a Delete button and a to do right under it, whereas in web we had the Delete button next to that to do. And so let's try to figure out exactly how we can get that Delete button over here and the to do to be next to it. And so does anybody have any ideas about how we might want to do that? We know we're going to have to pass a style prop, and we know that it's going to be an object. And so this looks weird to have those double curlies but the outer curlies mean, hey here comes some JavaScript and the inner curlies are just an object literal like we've seen before. And so how might we get those to dos to be in a row? So we saw before that React Native uses Flexbox in order to handle it's layout. And so we can just say, hey we want the flex direction, rather than being column by default, let's set it to row. And so now we have the Delete button next to the to do. But it's annoying me a little bit how that button is slightly below the text. And so how might we get those items to be aligned to center? Well in Flexbox we have this thing called align items and then you just say, hey align those to be center. Then all of a sudden we have it aligned center. And just confirming that delete button does indeed work. Great. Anybody notice any other bad style bugs over here? So look at this. So most phones will have some nav bar, and that nav bar will have stuff like if you're connected to Wi-Fi, the time and etc. But that first view is actually going all the way to the top. And so how might we get all this content to be slightly moved down? So how would we do that in Web? AUDIENCE: Add a margin. SPEAKER 1: Yeah we would add a margin or some padding or something to move the content from the top slightly down. And so we could do that in React Native as well. So you can say with this view, let's actually put a padding on the top and let's just say something like 50 which is somewhat arbitrary. And now we've gone ahead and moved that down slightly. But what if we wanted to move it down exactly the same amount as the status bar? Well there's this great tool called Expo which we'll talk about in length later today. They're also the people who designed Snack. And they actually give you this thing called constant so we can do import constants from Expo. And we can actually say, hey padding top rather than assigning an arbitrary value of 50 let's do constants.statusbarheight and that will actually give you that exact status bar height even if you're on different phones. And so, again, we'll talk about Expo and we'll talk about importing and exporting later today. But just FYI there's this thing called constants.statusbarheight which will give us exactly that status bar height. And now we have a to do app that doesn't look half bad. Cool. So there's actually this thing called style sheet which is part of React Native which has some optimizations for these styles. And so we talked about earlier how the way that your JavaScript communicates with the UI throughout is through this bridge. And so that means every single time you want a view with the style you need to send those style attributes over the bridge. There's actually a way that you can optimize this. And so the Facebook team created this thing called style sheet which does this for you. So it's basically the same thing as creating objects for style, but as an additional optimization that rather than sending this style object over the bridge we can only send IDs. And so say we have these objects, rather than passing the full object every time you can just say, hey this object, let's assign it this arbitrary ID of one. And so every time we say, hey this should have a style of one, the UI thread will know, oh, I know exactly what style that means. And so to do that, all we have to do is import this thing called style sheet from React Native and we can do this. And so we're saying we're declaring our styles as a constant outside of our app and we're saying, hey create this style sheet and we're going to pass into you an object where the keys map with how we're going to use this later. And so we can go ahead and abstract this out. And so we can say, this here we're actually going to call our to do container. And our to do container will just say, all right flex in the row direction and align your items to be centered. And then down here for style we just say, oh, we want to use styles.todocontainer. And let's actually lowercase this for convention. And as you can see those styles still get applied. And why else might this pattern be good? Does anybody see something better about this pattern? AUDIENCE: It's reusable. SPEAKER 1: Yeah exactly, it's reusable. And so say we wanted to have something else that had very similar styles to to do container we can actually use that again. And then if we wanted to change both of them at the same time we could do it by using this abstracted out object. And so let's do the app container and set that equal to this object. And then down here for this view let's do styles.appcontainer. And so there's actually an even better reason to do this and it's because every single time we rendered, we used to be building a new style object to pass. And now we're just using that same reference to that object that we created outside of this component. And so that's just an additional optimization that, using this pattern, creating the styles outside of the component allows us to do. Cool. Any questions on styles and styling? Great. So let's talk about event handling. So unlike Web not every component has every single interaction. And so in Web, if we had a div, we can assign an onClick to that div or if we add a list item or a list, anything we can assign an onClick to. But unlike Web there are only a few touchable components in React Native and those are a button, which we've used before. These three things called touchable opacity, touchable highlight and touchable without feedback, which are just three basic components that have slightly different reactions when you touch them. An then lastly, this thing called touchable native feedback which is this native component that you can only use on Android. And so in Web, when you had an event handler, that handler would receive that event as an argument. But that's not necessarily true for all React Native handlers. And so in order just to find out how those work you basically have to consult the documentation. The documentation for React Native is really good. I recommend that you peruse them just to see what components are available to you and those component APIs. And basically most of the stuff that you want to do is already pre-built for you. And so, even though there's no such thing as a checkbox component in React Native, there is actually a way to do that. And so let's go ahead and add this thing which is similar to a checkbox in that it's a Boolean flag but it's not really exactly stylistically the same. And so let's add this thing called a switch. As a switch you'll see what it looks like in a moment but it's basically just a Boolean flag that we're going to use in this example rather than using a checkbox. So before what we had here was an input of type checkbox and instead we're going to use a switch. And the value of that is going to be whether the props.TODO is checked. And so now when we add a TODO we see the switch that can be flipped back and forth. But if you notice, every time I try to flip it on it immediately turns back off. Can anybody spot why that's happening? So we have this value set to props.TODO checked, and down here do we ever update that value? No we don't. So we have this thing called Toggle TODO which we implemented last week, which, given some TODOs ID will flip that Boolean checked flag. But we never actually hook that up for this example. So in the TODO component here we're passing down an onToggle prop but we never actually use it up here. And so here we should actually have the switch when we do on-- what's it called-- on value change. And I only know this because that's what the documentation says. And so when that value changed, I should run props.onToggle, which is the name of the prop that we're passing down from this parent component. And so now when we click TODO it updates. And as you see right here the unchecked TODO count still updates as expected. And so now if we create a bunch we can see those numbers changing. We can see the checking and toggling works as expected. We see if we delete this one the TODO count goes down but the uncheck count does not go down since it was checked. If we delete something that isn't checked, both of them go down. And so we have the same behavior as we did in our React Web application. Any questions there? So we have this being a scroll view. But, if you notice, the scroll view gets cut off early and as we add TODOs it grows. But if we add a bunch of TODOs it grows with it. But say we actually wanted the scroll view to reach all the way to the bottom no matter how many TODOs were there. Does anybody know how we may go about doing that? The hint being that in order to control layout what we use is this thing called Flexbox. So by default components will grow to however big they need to be in order to fit their children. But we have a way of saying, hey fill as much space as you possibly can. And the way to do that is saying flex: 1. And so we want the app container to have a flex value of 1 so that the app container fills up all possible space. And so we could do something like app container let's do flex: 1. And then maybe for the TODOs, the scroll view here, maybe we want that to fill as well. And so we could go down to the scroll view and say the style is going to be flex: 1. But that isn't great design. What if we wanted instead to just have a style called Fill, which will just fill whatever space is available. And so that would be a good abstraction to have. So here we have a TODO container, we have an app container, and let's actually create this style called Fill, which we'll just flex: 1. And so now we can say hey, we want this scroll view to fill and we also want our app container to fill. But instead of adding that to app container, what would be a better way to do it? Well, we can actually apply both those styles. Does anybody remember how we could do that, apply multiple styles to the same component? So in React Web we would actually just give it multiple classes. What is the analog in React Native? We can actually just pass an array. And so say first apply styles.Appcontainer and then apply styles.fill. And now, if we add a bunch of TODOs we can see that it fills the available space. And then if we delete TODOs such that it doesn't fill the available space we see that it's not getting cut off at the bottom because it's filling all the way down to the bottom of this container. So any questions on event handling, styling or moving React Web to React Native components? No. So we've been talking about this thing called components, but we haven't really dived too deeply into what that really means. In the past few weeks, we've talked about how components return a node, how they represent a discrete piece of UI, how all components should act like pure functions with respect to their props. But that's really where we stopped talking about components. And so this week, we're going to dive more deeply into components and what components actually are. And so there are actually two types of components. And we've actually seen both of them already. So first is this thing called a stateless functional component. You might see it abbreviated as SFC or if you're reading blog posts online, some people call them pure functional components. And what those are basically just functions. So something like this TODO that we've created is just a function that takes in props and returns some node. It has no concept of state. And so that's why it's called a stateless functional component. It's just a function with no state. And the second is a react.component which we've been extending from but we haven't really talked about it too far in depth. And so first let's talk about stateless functional components. So this is the simplest type of component. You should use this when you don't need any state. And what it is is a function that takes props and returns a node. And it shouldn't do anything other than taking props and return a node. It should be what's called a pure function. In other words, it should not have any side effects, like setting a value or pushing to an array, updating an object, something like that because it should just take in props and return the value. If you do stuff other than that you might create some bugs or even worse crash your app or something like that. Then, any changes to the props that you passed to a stateless functional component will automatically cause that function to be re-invoked. And then after it re-invokes the function and returns nodes, React will do its thing and compare nodes to what it has in its virtual dom and then go ahead and replace what's needed. And so on the other side of the coin, we have what's called a React.component. This is something that's actually provided by the React library and implemented for you. And it's an abstract class that can be extended to behave however you want. And so, in our example here and examples prior, we've been doing this thing where we create a class called whatever we want and we're actually extending this thing called a React component. And so what is a React.component? Well these things have additional features that stateless functional components do not. One of those, of course, is that they have instances so they're a class. And so when you invoke that class it returns an instance and that instance will persist throughout the lifetime of this class. As suggested by the name, it maintains its own state and so stateless components do not, whereas these React components do. They have this concept of state, and we talked about state in depth last lecture. One thing we didn't talk about last lecture is this thing called a lifecycle, it's lifecycle methods. And so these are similar to hooks or event handlers. And so we've used the event handlers before in both React Web and React Native. And these things are actually automatically invoked for you. You don't have to worry about exactly the implementation details or when to invoke your own functions. That's actually something that's done automatically. And so unlike stateless functional components, which just take props and return a node, a React components render function actually becomes a function of the props and also any class properties that exist. And so if you remember back to last lecture we talked about classes and how when you create a class instance, you might attach to it some properties. These properties can be values anywhere from functions to just primitives, objects. And so when you create a class component instance, you can actually use all of those class properties in that render method. And so we saw that over here when we created this addTODO where within the render we referenced this.addTODO in this button component here. And so, as you see, this is a class property which we actually used in our render method. And so this render method is actually a function of both props and any class properties like its state or these methods that we defined. Cool. So I talked about this thing called a lifecycle method, but what actually is a component lifecycle. And so a component lifecycle can actually be represented by this graph. And so first a component will mount and so some lifecycle hooks get called there, but that's basically that constructor where the class instance gets created and maybe its state gets instantiated. And then what it does is it renders. It will just put you to the page. And then every time we call set state or get new props we actually enter what's called an update cycle. And so when you receive new props, the component needs to update. It needs to re-render. And so part of its lifecycle is actually updating over and over. And this happens any time new props get received because it wouldn't really make sense if we had a component that when it received new props nothing changed. But also this update cycle happens every single time the state changes. So if you call this .setstate, you update state and presumably you have something in the UI that also updates. And so this update cycle will happen again. And every single time you update state, receive new props this update cycle will fire again. And then, when it's time for that component to disappear, it enters what's called the unmount stage where you have the chance to clean up anything that you may have created during that lifecycle. And so what actually does that mean in practice? So I said that there's this thing called mount, which is basically just a series of steps that happens when a component first gets mounted and rendered. And so the first thing that happens is the constructor gets called. And so, as we saw a few lectures ago when we talked about classes, the constructor is where we have a chance to add class properties or add anything to that instance that we need. And so here we might want to do stuff like initialize state or maybe add some other class properties like bound methods et cetera. Next what happens is we render, which is just the meat of the component. The main goal of any component is to show you why. And so, in this render method, that's exactly what happens. You take any properties that you have, any class properties that you have, and then you end up returning a node. And then after that this hook, that we haven't seen yet, gets called a component div mount. And this is the chance for you to do anything that you wanted to do that didn't really matter for render. And so if you have asynched actions, like standing network or passes. If you want to add timers and stuff like that this is exactly where you should do that. And then maybe you'll need to update the state accordingly. And so if you actually see that state here this will cause a re-render without updating the UI. And so all of this will happen before the UI re-renders. And so let's play with that a little bit. So first let's copy this, that way you can keep it. So let's clear all of this and then play with mounting a little bit. And so in your next project what you're going to do is you're going to be implementing what's called a Pomodoro timer. And so for those of you who are aware of what those are-- basically what it is is a timer that allows you to switch between two amounts of time. And so there's this thing called the Pomodoro Technique which is used for studying where you study or work very hard for some amount of time and then you take a short break. And then you work hard for some short amount of time and then you take a short break. And so what you're going to be creating in your next project is actually a timer that allows you to do that. It will automatically track for you however long you want to work. And it will also allow you to set some time that you want to take a break in between those working blocks. And it will do that. So when you start the timer it will count down until you're done working. It will let you know, hey time for a break. Then it will switch over to that break timer, run down until that ends up and says, oh now it's time to work, and it will cycle through that. And so in order to do that, you might need to know how to work things like timers. And so these methods may be a chance for you to set up those timers. And so let's go ahead and do an example doing that. So first let's get rid of all of this stuff. So in this example we no longer need TODOs. And in our render lets actually just have some count. Those have a View. And inside here let's have some text. And that text is just going to show some count. And let's initialize that count to 0. So, as soon as I get rid of all this, we have a very simple app and all it does is show a count of 0. You see it up in this left hand corner here. And let's go ahead and actually center this. So let's do styles, and let's create a new style sheet. Let's call this app container and whatever we want to do in here. So let's have it grow as much as we can. Let's have it center its items. And let's have it align its items the other direction as well. And down here let's actually pass this in as styles.appcontainer. So now we see this number 0 is very small. Let's go ahead and make it a little bit bigger. And so let's have count and let's give it a big font size of like 48 or something. So now-- style-- we have a big number and all it does is 0. And so how are we going to get it to count? Well presumably we should be setting our state and just have that state increase. And so if we want to repeat something what might we use to achieve that? So do something at some given interval. We can actually use that set interval. And so let's first implement this count. So let's have this thing called increment. Is this too small? Let's have this thing called ink. And what that does is it does this.setstate, takes a previous state and returns the count to be 1 greater than the previous state. And so now we've implemented this thing called increment where we take the states count and increment it. And so how might we get this increment call to happen every once in a while? Well presumably we should use a thing called set interval, which we'll call a function every n milliseconds. But how are we going to get that to happen? Well we should do this after the component finishes mounting. We should set up some sort of timer. And so how do we know or how do we get a function to execute after components finish mounting? That's actually where this lifecycle method comes in. And so there's this lifecycle method called componentDidMount which automatically gets run for after the component mounts. And so we can actually set up our timer tap in there. And so we can do componentDidMount and inside of it we can do setInterval and that's called this.Increment every second. And so there's going to be a small bug here. Does anybody know what the bug is? So every 1,000 milliseconds this thing called this.Increment is getting called. And this.Increment is invoking this.Setstate. Does anybody see how that might be a problem? I'll give you a hint. It has something to do with this. And so when this gets executed this might not mean what this is here. And so this is a common bug in React. Oftentimes, when you say this here, what it means lexically is not necessarily what it means when it actually eventually gets run. And so how did we go about fixing this bug in previous lectures? We have to somehow get this to be bound to what we want it to be. And in case we want it to be bound lexically. So a few different ways to do that. One way was creating a new function here in line that does this. And I'm actually not sure that that works in this example because this isn't necessarily set here. The way we've generally handled this is by actually binding it at creation time. And so there's a shorthand whereby we can say when we create this increment function automatically bind it to this class. And so this is actually a new addition to the ECMAScript standard where this is called class properties whereby inline as we're declaring this class we can also create properties that should be added during the constructor. And so this is syntactically the same as doing this. Having the increment function defined as we did before. And in the constructor when this is created doing this.Increment equals this.Increment.bind whatever the this context we want to be. And in this case it's this. Or in other words, it's the same as just doing this.Increment is equal to the anonymous function that we defined down there. Whatever. And so that's just, rather than having to write everything in the constructor, we can just use this shorthand down here which is just generally the preferred way because it's easier to read. And now we've gone ahead and created this timer that runs. And so you can see that the numbers are going up. And the reason that this is happening is because we created this increment function. We correctly bound it to the this that we wanted to bind it to and then we said, hey, component when you're done mounting set up this timer, set up on an interval of 1,000 milliseconds. So every second call this increment function. And what does that increment function do? Well it updates the state to be the previous states count plus 1 and then down in the render we render this.state.count. And so you see every second the state gets updated to a new number, and the new number is shown there. And so we never had to manually say hey, run this code when you mount. We just created this method called component.DidMount and React handles automatically invoking that for you after the component mounted. And it's the same as the constructor. We never had to manually invoke the constructor. It just gets called automatically when a class instance is getting created? Any questions on the mount cycle or the mount processor I should say? Great so now let's talk about the update cycle. And so, just like in the mounting process, there is a bunch of lifecycle hooks that got called for you automatically. There are also a bunch of lifecycle hooks that get called automatically every single time we want to re-render. And so the first thing that happens is component will receive props which takes the next props. And so say you had something in your state that really depended on what the props were set to, you can actually use this function to update any of those state fields that rely on the props. And you do that by calling this .setstate. Next is this thing called shouldComponentUpdate, which takes the next props and the next date, and here you can compare change values and decide whether or not you want that component to render. And you can actually stop the update cycle here. And so this is a good optimization. So say you have a very complicated component that takes a really long time to render you don't necessarily want it to render every single time you get a new prop because it might be that the new prop doesn't actually change anything that's shown. And so you could use this method to stop it early. But that adds a lot of complexity to your app and there's almost always a premature optimization. The next happens render, we know exactly what happens there. And last we have this thing called ComponentDidUpdate, whereby you can do anything that isn't needed for the UI, like network requests, which is basically the analog for ComponentDidMount. And so let's see an example for this update. So say rather than just rendering this text we actually pass this count to another function. So let's have this thing called a count, which takes as a propped account. And then let's create this class called count. And then here, let's first just render the text. And so now we're back to where we started, where we basically have some text that gets rendered based on this.PropsAccount, and let's style it to be larger. And so now we're basically back to exactly where we started. We have this app which automatically increments and then it passes whatever its state count is as the count prop to this other class that we call count. And then this component we basically just take that prop and render that text. But say we actually only wanted to update on odd numbers. So say we want to create a new-- or say we want to have this be called CountEvennumbers. And so, in this example here, how might we say, hey don't actually update unless your number is even? Right now every single time it receives a new prop it's updating. But say we only wanted to count even numbers, what's some strategy that we may use in order to skip the rendering for odd numbers and only render on even numbers? AUDIENCE: You could use [INAUDIBLE] before an update. SPEAKER 1: Yeah, so we have this thing called shouldComponentUpdate, which takes the next props. And so we have the ability to look at the next props and decide whether or not we want to update, and if we return false from this function, the update cycle is over. It won't render. And so if in this function we wanted to check if that count were odd we can abort early. And so let's actually do that. So let's have this method called shouldComponentUpdate and first let's just return false. Now what's going to happen here? Nothing. We can see that it's receiving stuff. So see down here in the logs we're receiving this thing called updating every second. But the UI is just stuck at 0, it never updates and that's because we're saying hey, should the component update? No we shouldn't. And so React is saying, OK, then we're not going to call this render method and nothing changes over here. And so how may we change this is such that it only counts the even numbers? Well we can say return, check to see if the next Props.count is divisible by 2. And, if it returns true, that means we're an odd number. But what we want is whether we're an even number. And so we can actually just say, oh, return the inverse of this. And now it's only going to count those even numbers. Does that make sense? And so say we wanted to do something like send a request or server every single time this UI updated, we wouldn't really want to do that in the render cycle, we wouldn't really want to do it in shouldComponentUpdate. We can actually do that in ComponentDidUpdate. And so we can actually do for now let's just console.log. We can say, hey, we updated it and we created a new number. And as you see, it's only getting called for those even numbers. Because first shouldComponentUpdate gets called and then it renders and then ComponentDidUpdate gets called. And, since we exit early on all odd numbers, only the even numbers will reach the render cycle and ComponentDidUpdate. And so what you see logged are only those even numbers. So does this concept of updating and methods that automatically get invoked makes sense to everyone? AUDIENCE: Could you only do this kind of stuff with [INAUDIBLE] and not the purely functional ones? SPEAKER 1: Yeah. So the question was, do these methods exist on the functional ones? And they don't because, say this functional components are literally just functions. They take props and they return a node. And so since they're functions, all they do are get invoked. You pass them props and then you get a node back. And in order to have these methods you actually have to have this concept of an instance. And so React components have instances, and these instances are tracked throughout their lifecycle. And since these are class instances React well go ahead and invoke those methods for you. And so the stateless functional components are just functions that get invoked and do not have these class methods, whereas the React components not only have these methods but the methods also get invoked automatically for you. But yeah great question. So that's the update cycle. And then lastly we have what's called the unmount cycle. There's only one thing that happens in the unmount cycle. You have componentWillUnmount which gives you a chance to clean up. What do I mean by clean up? Well, you can remove any event listeners if you had them in React, mostly Web. You can invalidate any network requests that you have out. Or lastly you should clear any timeouts or intervals. And so there's actually some bugs that you can create if you're not careful. So let's actually revert this back to being just an app that shows that count. So now we have again that number being incremented. And this class called app keeps track of its own number and is updating. But say, let's actually call this counter and create this thing called app. And in this, let's actually just show the component. So now we have basically the same exact thing. So we have this thing called class app which just returns an instance of counter. And counter is what we've been working on thus far. It creates an interval and we'll keep track of that interval and keep counting up. But say we actually have this button that will toggle whether or not this counter is shown. And so let's have this thing called state and let's have this flag called show counter and let's initialize it to true. And then down here we can do something like, if you should show the counter then return this. Else let's just return an empty view. And so now this is basically the exact same thing because we have no way to change whether or not we want to show the counter. But say we did, so let's create toggleCounter. So show counter. It should be the opposite of what the previous state show counter was. And let's also have a button that will toggle this counter. And so now we have a button where if we click it, we can just toggle whether or not that counter shows. And there's actually a pretty bad bug here. And that is that when we toggled this counter-- oops, we should return this-- when you toggle that counter we never actually tell this component, hey, stop incrementing. It's actually going to keep incrementing. And so we can show that if we have here, if we console that log we see that it's incrementing, and if we toggle it, it's still logging. So counters now gone. So there's no counter here, it's gone but it keeps saying increment. And, if we show it again, now look at how fast it's incrementing. It's two every second because the first counter created an incrementing function every 1,000 milliseconds and the second time we created one it also did. And so what if we did this again. Toggle and then toggle again. Now it's going up three every second. And if we did this a bunch of times, you see it's going pretty crazy now. It's like five every second. And so that's not good. That's definitely not good at all. Say you had a super complex app and hundreds of timers getting set and you kept toggling them. Eventually you're going to have a big problem where a bunch of things are getting called and nothing should be getting called. And so that's like a memory leak and it could cause your app to crash. And so how might we go about solving this? So, as we alluded to, there's this thing called an unmount cycle where we have a chance to clean up. We can get rid of any timers that we've created. And so you can actually do that here. And so, rather than just setting the interval, we should actually track that function that we created. And so you can do something like this.Interval equals setInterval. And so setInterval actually returns like an ID of the interval that you created. And so now we're tracking exactly the interval that we created. And we can go ahead and right before this component dies, so component will unmount, we should actually clean that up. We can actually do clearInterval and we pass in that ID. And so now you can see-- oops, things did not get updated. Let's actually copy all this and refresh the page. And so when this loads, you'll see that it will still log when it's getting shown. And so as this number is incrementing we can see it saying, oh I'm incrementing. But when we toggle it that number no longer goes up. And then, if we toggle it again, it's going to continue incrementing. And, if we cancel that, that incrementing function is no longer getting called. And that's because, over here, when the component was created, so when the component mounts, we set the interval for this button increment to happen every 1,000 seconds. But then later when we are no longer returning that counter so the instance gets unmounted. It's no longer part of the React tree. Before it gets unmounted, we say clear that interval and it clears. And then when it remounts it creates a new interval. And when it gets unmounted again it goes ahead and clears that interval. And so now we no longer have any memory leaks. So does that whole lifecycle process make sense to people? Do you have any questions about these methods or why we might want to use them? Cool. Let's take a quick five minute break and then after this, we'll go ahead and start writing some React Native. Hello and welcome back. So if you are following Snack some people had some questions about style and whether or not people in industry chose to bundle this style with each component. And what I tend to see mostly in industry is that people do indeed tend to include the styles with each component because part of React's component mindset is that each component should be a standalone thing and it should include with it any event handlers or JavaScript and any style as well. But there are many compelling reasons to actually remove the style outside of that component. And one big compelling reason would be something like color themes. So say you had some color theme where you really liked crimson in your app and everywhere you were using crimson. And then say suddenly you wanted to use something like blue. If you had everything hard coded to crimson it might be a bit of a pain to go through and find every instance of that crimson and change it to blue. But say you actually abstracted out some value like primary color and instead used that in all of your components. Then if you wanted to change the primary color from crimson to blue it would be very easy. You would just do it in one file and be done. So there are definitely compelling reasons to remove the styles out of a particular component. And since React Native uses JavaScript's objects to style components it allows you to do stuff like create variables and import them in. And so are there reasons to take the style sheets outside of any particular component. But generally if you have a choice it's easier to just leave it in there for organization sake. Cool. And so up until now we've been writing a lot of React Native in this browser environment. And so let's actually figure out and talk about how we actually write React Native if you were to start your own personal project or assignment for the course. So I've been talking about this company called Expo quite a bit. And what they do is they create a very fast way to build an app. They provide a lot of tooling around React Native and the React native community. So there are a suite of tools to accelerate the React Native development process. And so one that we've been using quite a lot is this thing called Snack, which is this website here. We've used it this course, a lot this lecture and last. And what that allows us to do is run React Native in the browser. So it automatically bundles any libraries that we need like React Native, React, and then it also runs on a phone embedded into the browser. They also give us a tool called the XDE which is a GUI, graphical user interface, to serve share and publish any Expo projects that you have. They also give us a command line interface to do the same things, to be a command line. They give us the Expo client which, if you saw my email from earlier, is an iPhone app that you can install and actually run stuff that you write in Snack or stuff that you write and manage by the XDE or the CLI to actually run it on your phone while developing and before you publish. And lastly they give us an SDK, software development kit, which bundles and exposes cross-platform libraries and APIs. And so included in that are maps, stuff for like icons and images and SVGs and maybe animations. They also give us handy constants. So the Expo that we imported into this app is actually the SDK, and it gave us a constant like, we didn't use it here but, the height of the status bar. And so they give us a lot of helpful things to really get our developing process moving forward. And so let's take a look at this thing called the XDE. So I have it here. It's a little bit small but basically what this is is it allows us to create and run projects. And so I actually already created this project before the class, but when you do create your project it allows you to choose a template and basically create the directory and all of its dependencies on your computer. And so, if you started with the blank like I did and created my new project, it gives you a chance to save it wherever you'd like. But I already went and did that process and created my new project. And so, if you want to follow along at home, you just do create new project, blank, save it wherever you like and then you end up right here. And basically what this is, is this is running a bunch of things behind the scenes including React Native packager which handles the bundling and whatnot of your app and any logs if you want to console log, will also appear in this XDE. And so what it's doing is it's actually looking in that directory that it created on your computer. And so if you create it and then CD into the correct directory on your computer you end up right here. And so when you create a new file you see this thing called app.json which is basically a bunch of metadata that's created about your project and is how Expo tracks your app. And then you see this thing called app.js. And that is basically the bare bones React Native app that you start with. And when you run it, if you open it up on a device, you see it run here. And so this says, open up app.js to start working on your app. And if I were to change the text here and save, we can see it re-bundle. It's currently building that new JavaScript bundle and then you see here, live on the phone, that you did update that text. And so, if you want to start working on your project earlier or work on any personal projects of your own, you're welcome to use Expo. I actually encourage you to use Expo because they take a lot of annoying and difficult parts about creating projects and publishing them and do all the hard work for you so that all you have to worry about is writing the JavaScript here. Cool. And so we've been doing this thing a lot in this lecture and previous ones called importing and exporting. And we haven't actually talked about what is. And so we have talked a lot about components and how we should break up components. And it's actually also highly encouraged that you break up the components into their own files. And so we've seen that components are great for simplifying your code and we can actually split them into their own files. And then what this allows us to do is help organize the project even more. Rather than having everything all in one big super long file, which might get very unwieldy, we can actually organize things into their own separate files or even separate folders so it's easy to find whatever code you need to update. Then what we do is from the file that we create we actually export the component that we want. And then we can then import it in to another file if we want to use it. And there are a couple different ways to import and export. There's this thing called a default export, and there's this thing called a named import and export. And so what I was typing a lot earlier is you see me type this thing called export default class app. And that's me saying, hey from this file here I actually want to export this app. And it should be the default export. And so let's take a look at what that looks here. And so in app.js in a brand new directory I went and-- the boiler plate code says export this default class app. But say I want to in a new file. So let me create a new file called let's just call it count.js. From here let's first import from React, which is something that we have to do in every single file. And let's create this component called Count. So let's do const Count equals props and then let's return this thing called a view. And then have props.count show. Actually, let's have this be text. So this won't actually work because we're using this component called Text here which doesn't exist. So Text here, capital T capital Text, is a component but this file has no idea what Text is, what capital Text is. It's a component. We know it's a component because it's in JSX and capitalized but nowhere in this file do we declare this thing called Text. And so we actually have to import it from the library called React Native. And so you've seen me before in the example files do this thing called import Text from React Native. And what that the actually does is it goes into that React Native API code and gives you access to the variable that they're exporting called Text. And then when we go ahead and use it here the JavaScript knows that this variable context exists. And so how are we going to get this component called Count into our app? So say I wanted to hear a display count and passed an account of 0. So if I save this and try to run it, it's going to error because this variable called Count doesn't exist, which makes sense right? In this app.js file we haven't created a variable called Count. We actually created it in a separate file called count.js. And so as I alluded to, you can actually export a component from a file and import it into a new file. And so we can actually, over here, just use this term called export. And if we go ahead and save this then now we can try to import this thing called Count from-- where is it? Well, it's in the current directory, so ./Count.js. And so now if we save that we can see that it compiles and we see that 0 show up. And so let's make it a little bit bigger so that's easier to see. And so how are we going to do that? Let's create this constant called styles and let's have stylesheet.create. And let's just have a font size of 72. And then here let's just do style is that Styles object that we created. And if we save this and run it what's going to happen? It's going to error. And why is it erroring? Well it says cannot find variable called stylesheet, which makes sense right? In this file here nowhere is there a variable called stylesheet. And so we actually also have to import that from React Native. And so if we run that and save it, lo and behold, it rhymes and the style is applied. We see a big number 0 there. And so that is called a named export. We exported a named variable called Count. And then in here in brackets we say import all of the variables named Count that we exported from ./Count.js. And so that is an example of a named export. And say we wanted to export another named variable we can do export const-- let's just call it num, and let's have it be the number 50. And we can, over here, do import Count and also num count.js. And then rather than passing in 0 we can just pass in num. And as we see over here now it's the number 50. Why is that? Well in Count.js we exported two variables. One we called Count, so capital Count here. We have a const called Count and we're exporting that. And so it's a named variable that's getting exported. Over here we have a constant called num, and we're exporting that, so there's also a named variable called num that's getting exported. Then over here in our app file we actually import to this thing called Count and num. And so the names do matter because it needs to know exactly what we're importing in. And then we go ahead and use those and they show up as expected. And so those are called named imports and named exports but there's also this thing called a default export. And so you see here we have an additional term called export default this value. And so in our Count file over here let's get rid of-- or let's not actually get rid of anything and let's actually do export default. And then just give it a value to export. So export default this function that we're creating and if we want to make this more obvious what's happening here we can actually do const Count equals this. And then we can do export default Count, which is saying set the default export of this file to be Count. And then how are we going to import it? Well, rather than importing these name things we just say we want to import this thing from Count.js. And since we've dropped those brackets we say just import whatever is default exporting. And we're going to call it here Count. And so if you notice it works-- oops as long as I save all the files but I never-- let's change this back to 0. And so now as you notice it is showing that 0 value as expected. But let's actually call this something else. So let's call this custom Count. So even though over here we're exporting a variable called Count, since we're are using it as a default export, we can import the default export in this file and call it whatever you want. And so we can call it custom Count over here and it still works as expected. And so the difference between named and default exports are that named, 1, you can export multiple of named exports and also import to multiple named exports from a different file. And they do have to be named exactly as they are in the other files. But when you export something default you're limited to only exporting one which makes sense. If you exported multiple defaults you wouldn't know which one to import. And then over here, you can call it whatever you want because it doesn't matter, it's just the default export. And so that's how you're going to go about starting to remove components from one long file and move them into separate files. And so you can also actually import the export default and also named exports. So here we are exporting a named export and we're also having a default export. And in here we're importing the default and we're also importing a named export and, as you see, that works as well. And so over here you see that we are importing React from React which is whatever its default export is. We could also import one of its named exports, and rather than extending a React.component we can just extend component here because we went ahead and imported the named export called component from React. And so that will also work as well. So any questions on importing and exporting and how you would go about breaking up particular components into separate files? Yeah. AUDIENCE: You were able to access the components with React.components. Is that because the component is [INAUDIBLE] named export and the value in the React.components? SPEAKER 1: Yes exactly. So the question was, I was able to access component as React.component and separately also as component and that's because this thing called component is actually a property on this React. And so what React exports is both a default export, which is this massive thing where one of its object keys is called a component and has the value of the component and it's also separately exporting a named export called component. And so we can go ahead and either import the default export and do that .component or we can import the named component and just use that. So you're absolutely correct. Any other questions on importing and exporting? Cool. So when we go ahead and import and export components they can start to get more and more complex as we pass down more props. And so how might we go about keeping track of all of these props? Well React actually has a way to help you with that, and it's called prop types. And so React can actually validate the types of a given components props at runtime which is great. It's a development tool that allows you as a developer to ensure that you're passing the props that you think you're actually passing down. And so say you're passing down some prop that's a number but you actually want it as a string. It's very easy, as your project scales up, to kind of get those mixed up and maybe you pass down a string when you meant to pass down a number or vise versa. And so this thing called PropTypes allows you to keep track of that. And React will actually do this automatically in development mode. And this is also great because it helps document your APIs. And so I have this very simple component over here called Count and it takes a single prop called Count. But say it also took three other props and say it also had 10 other components that also took their own props. It might get kind of hard to remember that as I scale the project. And say you're somebody like Facebook who have something like 30,000 different components in production it would be very painful to not have those documented and have to go and read the code to know exactly what props you should be passing. And so by declaring this thing called PropTypes you actually can help self document all of these APIs. And what's nice is this only runs in development mode and so you don't have to worry about it slowing down your production in production mode. And so how might we go about doing that? There's actually a package called PropTypes. It used to be bundled as part of React but they've since split it into its own module though it's still maintained by Facebook. So we can go ahead and do this thing called import PropTypes from a package called prop-types. And so now we have access to this variable called PropTypes where importing the default export of whatever this library called PropTypes is. And so now we can go ahead and use that in our file. And so let's go ahead and do Count. And so we created this variable called Count, which is a function of a stateless functional component. And we can actually attached to it a property called propTypes. Note that it's a lower case p here. And I can set it equal to an object and the keys of this object will map to whatever props that I expect. And so in this case we expect a single prop called Count. And so I can say Count should be of what type, well PropTypes. So capital P here is referring to the library that we just imported. And we can say we want a number, and it's required. And so now we see this warning. We see, hey, there's a failed prop type here. The prop count is marked as required in this component called Count but it's values undefined. Why is it undefined? Well because we're importing this thing called number and we're passing this thing called number over here. But we're not actually exporting anything called number in this module. And say we actually remove that and passed a 0 here. Now it'll run as expected. There are no warnings thrown. And now let's try simulating a mistake where rather than passing the number 0 we go ahead and pass the string 0. The app will still work because we're just displaying whatever we pass. But if you notice we have a warning here. Warning: Failed prop type. Invalid prop count of type string supplied to count. We were actually expecting a number. And so that's actually React's built-in prop type system which is checking against the types that we're passing down here. We say, hey we're expecting this thing as a number but since we pass a string it will throw a warning for us just to let us know, oh by the way I don't know if you know this or not, but you're passing the wrong type down. And so we can use this thing called prop types in order to validate the props that were passed. And so in stateless functional components we actually just add this as a property. But say this were actually a class component. So let's do class Count, extends React.component. And then we have a render which will just return this. And let's fix some styling so it's easier to read. So now we have a class component and as long as there are no syntax errors-- There's a syntax error somewhere that I don't see. Does anybody see the syntax error? Can anybody beat me to it? AUDIENCE: Is that last a parentheses or is that a bracket? SPEAKER 1: This here is a parentheses. Oh, yep. Nice catch. I owe you some candy. So now if we go ahead and reload this, it can't find the called props because class component is stored as this.props. And now we can go ahead and see that it is as expected. We still have that failed prop type message because we're passing a string rather than a number but it's working. And so we can go ahead and so we create the class here. And then we go ahead and do Count.propTypes here which works. But generally the way that you see the convention is actually to use this thing called a static method. And so there's actually a static keyword where you can do static propTypes equals that object. So functionally exactly the same, but the convention is to use this thing called a static method or a static property because it's just the way that the new class index works. And so it's functionally the same as doing count.propTypes down here, but the convention is just to use the newer syntax. So any questions on PropTypes? Does everybody see the utility of using them? They've definitely saved me multiple times on personal projects. And so now, if we've passed the correct props, there are no warnings. Great. And the last concept I wanted to touch on is just how the heck do I read docs. Because I can't possibly teach you every single component that React Native offers. But they do offer a lot of great components that you may want to use in either project for this class or maybe a personal project that you're working on. And so here's basically the steps that I go through in order to figure out what I should use when working on my own project. So first have a goal in mind. You need to know what problem you're trying to solve. Otherwise reading a bunch about what's offered doesn't really mean anything to you. And so say you were doing something like the TODO app that we did before the first thing that you'll notice is that there is no input type checkbox in React Native. And so you have to figure out what is my goal here? Well I want to replace what used to be a checkbox. And so your goal in that example would be all right I need some component that basically just renders a Boolean. Then just see what the library or framework offers. And so the way I did that was I just browsed through the docs. So they're linked in this presentation. I'll go ahead and link them in the Resources tab on the website. But just see exactly what the library has to offer, see what they have, then find something that solves your problem. There may be multiple things that solve your problem but just try to find the thing that best solves your problem. And so in my case for that particular Boolean switch I saw that they had something called a switch that just renders a Boolean flag that you can just tap and then configure it. And so the docs will tell you exactly what the API is, how you can configure it, what properties you have to set. And so for switch we had the value which was either true or false. And we had on value change which was, I believe, the name of the prop that gets called every single time you change that value. And so it just fit that API to whatever you're using. And then, of course, if you have trouble even then, then you can turn to the community. A great thing about React, React Native is the community. Lots and lots of people use React, lots and lots of people use React Native and a lot of them are experts who were once beginners themselves. And everybody remembers when they were first learning React and React Native there's just a lot around and there's a lot of stuff in the ecosystem. And the community's really great in helping each other learn what's around and how to best solve their problems. And so just ask the question. You can ask it in Slack if you're part of a class. You can ask it on something like Stack Overflow or just Google around. And so if you run into a problem odds are somebody else has already run into the problem and odds are somebody better than you, better than I have solved that problem. And you can go ahead and use their solution. And so any time you get stuck feel free to either browse the documentation yourself or reach out to the staff with any questions. And so, yeah, that's all I have for you today. Good luck starting your project. It will be released before next Monday.