[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.