COLTON OGDEN: All right.
Hello, world.
This is CS50 on Twitch.
I'm Colton Ogden.
I'm joined today by CS50's Brian Yu.
Brian, what will you be
talking to us today about?
BRIAN YU: Hey, everyone.
Today we're going to be talking about
React, which is a web framework that's
designed to help make it easier to
develop dynamic web applications that
have interactive user interfaces.
So we'll be taking a look at
how to get started with that,
some of the basic features of it.
We'll only scratch the surface
because there's a lot to React,
but hopefully you'll learn enough
over the course of the next two hours
or so to get a good sense
for how to use React to build
a web application of your very own.
COLTON OGDEN: And Brian is CS50's
head teaching fellow currently,
and also taught a course through the
Extension School, the web course.
Let me just plug that really
fast here. cs50.nx.org/web,
if anybody's interested.
What were some of the topics that
you taught in that web class?
BRIAN YU: Yeah, the web development
course was a course we ran last spring.
It was about web application
development using Python and JavaScript,
so we talked about continuing
where CS50 leaves off,
talking about the design and
implementation of web applications
using Flask.
We moved to a more advanced
Python based web framework
called Django that has a bunch
of additional features as well.
And throughout the
course, we were talking
about issues of database design
and security and scalability,
and ultimately how to design and deploy
web applications on the internet.
So all of those lectures that are
freely available online, definitely
feel free to check those out if that's
something that's interesting to you.
COLTON OGDEN: And so would you say
that's more of a back end course,
and what we're doing today is a
little bit more on the front end?
BRIAN YU: Yeah, I'd say that
there was a lot of back end
work over the course of that class
where we were teaching things
about how to design API, for instance,
how to design ORMs for interacting
with databases in particular, although
we did touch on some JavaScript
on the front end.
Today is going to be entirely front end.
React is really a framework designed
for front end web development,
and you can connect it with
just about any back end
that you use, not necessarily
written in JavaScript.
You could connect it with
a Flask or Django app,
for instance, or some other web server.
COLTON OGDEN: OK.
Super excited.
I know React is one of the
big front end frameworks.
Is it the biggest one?
BRIAN YU: As of right
now, it's the biggest.
So these web frameworks sort of come and
go, and they sometimes get more popular
and lose popularity.
Right now, React is number
one in terms of popularity.
Number two is Angular, which
is developed by Google.
The Angular 2 is a relatively
recent addition to the mix,
and then there are other
frameworks as well,
such as View that are also
growing in popularity as well.
COLTON OGDEN: Awesome.
So we've got a couple of
comments there in the chat.
We've got some regulars here.
So Bavick Knight and [INAUDIBLE] are
regular folks who join us all the time.
Say, I'm on time today, says Bavick.
[INAUDIBLE] saying hello, how are you.
M Kloppenberg says, hello, everybody.
Good to see you, M
Kloppenberg, And oh, it
looks like Bavick says he's
enrolled in the web course.
I want to learn more about
it, about Django, he says.
BRIAN YU: All right.
Great.
Glad to hear you enrolled.
Yeah, Django comes a little more
than halfway through the course.
It gives us an opportunity to start
to talk about testing our code
in order to make sure that
our routes work properly,
and it gives us an opportunity to talk
about security and some other issues.
So definitely look forward to that.
COLTON OGDEN: Awesome.
Cool.
Cool.
All right, well, do you want me
to bring your computer up here
and we can start taking a look?
BRIAN YU: Yeah, sure.
Let's do it.
So let's start by working on a very
simple web front end using Django,
and what I have here
is just a basic HTML
file, the same way that you
would design any other HTML
file if I were building a web page.
But what you'll notice right
here just to start us off,
I've added three
scripts that we're going
to use in order to allow us to add
some React code into this HTML file.
So the first one up here on line four,
I am importing the React library itself,
the development version
of the React library.
On the next line, I'm importing a
related library called ReactDOM.
This is going to be a
library that's going
to give us the ability
to take some React code
and actually render
it inside of the DOM.
And if you're unfamiliar, the
DOM or the document object model
describes the structure of the web
page, because we're going to say,
we're going to add some HTML
element to this web page eventually,
and we're going to
say, this HTML element
is one where we want to play
some React elements inside of it.
And so we'll place some
of what are actually
called React components,
inside of our HTML page,
and ReactDOM is going
to help us do that.
And React is interesting in the
sense that while you can write it
in pure JavaScript,
the convention nowadays
is to use something called JSX.
It's not just JavaScript,
but JavaScript X,
where the convention is to mix our
JavaScript and our HTML elements
together.
Where in JavaScript natively, things
like integers and strings and functions
can all be considered values, in JSX, we
can consider HTML elements to be values
as well, and we can use regular
HTML like syntax in order
to define an HTML element that we
could save to a variable, for instance,
and put in a list of
other HTML elements,
which gives us a lot of
expressive power, which
we'll see in just a moment.
And so this last script
right here, Babel,
that's going to take care
of translating the JSX
code into regular
JavaScript which our web
browser is going to be able to
understand such that we can render it.
So let's go ahead and get started by
building something very, very simple.
So inside of the body
of my web application,
the first thing I'm
going to do is create
an area inside of the
body of my application
where this React application
is going to live.
And generally speaking, this
is going to be a div element.
A div just defines some
block of the web page
where some particular HTML
content is going to go,
and this div is going
to have an ID of App,
because app is just an arbitrary
name that we're saying,
but we're going to identify
this div by the ID.
The ID is App, such that
later in the JavaScript code
that we're about to
write, we're going to say
take some React component
or some piece of React code
and insert it into the div called app.
So we're giving it a name such that
later, we can begin to reference it.
COLTON OGDEN: It looks like Shana G
says hello with the Bob Ross icon.
I think it's become a
trope, the streams that
make some people feel like we're
watching a CS version of Bob Ross.
Bavick Knight says how is React
different from Ajax and jQuery?
BRIAN YU: Good question.
So Ajax is sort of separate.
The idea of Ajax is just the
mechanism of a client asking
a server for additional information
without needing to reload the page,
for instance.
So for instance, if you're in a chat
application on Facebook Messenger,
or GroupMe or WhatsApp or whatever chat
application you happen to be using,
and someone sends you
a message, you don't
need to refresh that page in
order to get the next message,
and that's due to some technology.
Web sockets are a
popular way to do that,
but you could do this
using something like Ajax,
where the idea is that
you are asking the web
server for additional information,
and that new information gets
loaded on the page without you
necessarily having to do anything.
So for instance, this is the
way Twitter, for instance,
might go about loading new tweets.
If new tweets come in while
you're still on a page,
if you were watching the New
York Times website last night
and you lived in the United States,
for the US midterm elections
you saw a similar thing, where you
didn't have to refresh the New York
Times page, but new content about the
latest election results were coming in.
That can all be done
via Ajax, for instance.
And jQuery, meanwhile, is
an older JavaScript library,
and that JavaScript library is
designed to make some things easier,
in particular trying to
select elements and trying
to modify elements in particular ways.
And so you can certainly use
pure JavaScript or jQuery
to do a lot of the
things that React can do.
React is just designed
to allow for what we
had called stateful components,
components that can update
based on some sort of internal state.
And we'll see an
example of that shortly.
COLTON OGDEN: Would you maybe use React
and Ajax together in an application?
BRIAN YU: Yeah, certainly.
If you had a React front end and
some sort of back end server,
you might, inside of your
React code, make Ajax requests,
make calls to a web server in order
to ask for additional information
that you would then render
inside of your web application.
We won't see that today,
but definitely something
that you could do using React.
COLTON OGDEN: Nuanda 3333,
who's [INAUDIBLE] says, finally
JavaScript with heart.
So people have been
very excited for that.
Very thorough explanation.
Wow.
Best says, Bavick Knight.
Awesome.
BRIAN YU: All right.
So we have this div right
now that just says App,
but right now this div is empty.
So this slash then
greater than symbol just
means there's nothing inside
of this div right now.
And in fact, if I were to go
ahead and open index.html inside
of my web browser chrome, what you'll
notice is right now, it's blank.
There's nothing there.
So let's go ahead and put
something inside of this web page
such that we can do something
interesting with it.
And to do this, I'm going
to use some JavaScript code.
So I'm going to put this
JavaScript inside of a script tag,
but because I'm going to
be writing JavaScript X,
JSX code instead of pure
JavaScript, what I need to do
is transpile that code from
JSX into regular JavaScript
that my web browser is going
to be able to understand.
And so to do that, I'm going
to say this script's type
is going to be text/babel,
and what that's
going to say is that Babel,
which is the technology that's
going to do this transpilation for
us, is going to take this code,
and before it actually renders the
page, the first thing it's going to do
is transpile or translate this code into
regular JavaScript such that Chrome,
my web browser, which
doesn't understand JSX
but does understand pure JavaScript,
is going to be able to understand it.
So what's the code that
I'm going to write?
Well, in general, we're going
to create React components.
So any piece of your website you can
generally consider to be a component,
and one way that React likes
to think about user interfaces
is by taking a user
interface and dividing it
up into the different
components that make it up.
So for instance, an application might
have a menu bar that has a component.
It might have a form that
has a particular component.
A visualization of data in a
particular way might be a component.
And components can even be
nested within each other.
You can have a component that has
components inside of it, for instance.
COLTON OGDEN: Like a form can have
a bunch of subcomponents, like text
fields and dropdowns
and stuff like that.
BRIAN YU: Yeah, certainly.
That definitely would be possible.
COLTON OGDEN: Gossen
says, is Bootstrap--
I'm assuming he means Bootstrap the
framework-- different from React?
BRIAN YU: Good question.
So Bootstrap is a CSS
and JavaScript library
that's designed to help
style our websites a little
more easily and add some basic
interactive features, things like form
validation that Bootstrap allows for.
It is different, but you
can use them together.
So React is going to
be what's taking care
of the logic of like what ultimately
gets displayed on the page based
on the state of the
website, as we'll soon see,
and you could add Bootstrap to
this application in order to say,
I want to style this web
page in a particular way,
and Bootstrap offers some great CSS
code that just makes a website look
a whole lot more modern
and look a whole lot better
without you having go
through the effort of writing
a lot of that same CSS for yourself.
And so you could definitely
use these in conjunction.
COLTON OGDEN: Awesome.
BRIAN YU: All right, so we're
going to create a React component,
and to do that, we're going to use the
latest version of JavaScript that's
called ES6, and it allows
us to define classes.
So this is something you may
be familiar with if you're
familiar with other object
oriented programming
languages, like Java for instance.
But the idea of a class is, we're
going to define what this component is,
and then we can instantiate that class,
or say, let's create a new component
and put it somewhere inside
of my web application.
And so I'm going to define
a basic class, which
is going to be called Hello, which is
just going to be a React component that
is going to say hello on my page.
And I'm going to say this class Hello
is going to extend react.component.
So the idea here, if you're familiar
with object oriented programming,
is that the Hello class is going to
inherit from the React component class.
But if you're not familiar with object
oriented programming, totally OK.
The basic takeaway here is that Hello
is an example of such a component.
All right, so we have
this React component,
and what we need to tell this component
is, what should this component do when
we tried to render it to the screen,
when we try to render it inside
of the DOM, render it on this web page.
And to do that, we're going to
give it a method called Render,
and this Render method
or function is going
to return what it is that gets
displayed on the page when
I try to render this component.
And so let me return something.
And what I'm going to return is a div
that just says hello, for instance.
And so this syntax of div
followed by Hello and then /div,
this is something you might see in
just regular HTML, for instance.
This is just an HTML
element inside of which
is, Hello, the text that I want
to display inside of this div,
and my render function is just
saying, Hello is the thing
that I want to return when
someone tries to render
this component onto the screen.
COLTON OGDEN: So to actually get to
render, or return like sort of raw HTML
within our JavaScript, is something we
normally definitely don't get to do.
BRIAN YU: Exactly.
We can just expressively
put the HTML that we
want to show inside the page right
inside of that Render function,
this is an example of that JSX syntax,
that mixing of HTML elements along
with our JavaScript syntax.
COLTON OGDEN: Awesome.
BRIAN YU: So we've defined
this class called Hello,
but we haven't yet rendered the
Hello element, this component, inside
of my HTML page just yet.
So that's the last step.
So down underneath the class definition,
I'm going to say ReactDOM.render,
meaning I want to render
some React component,
and the component I
want to render is Hello.
And we're going to treat
Hello almost as though it's
an HTML tag, the same way that
div is a tag or body is a tag,
and I'm just going to say, let's
render this Hello React component.
And where do I want to render it?
Well, I want to render it back up
here where I said, all right, we
have this div whose idea is App.
That's where I want to
render this component
inside of the body of my page.
So I'm going to say let's
render this Hello component
inside of that part of the page.
And if you're familiar with
JavaScript, one thing we can use
is something called
document.queryselector,
which is a built in
JavaScript function that's
going to allow me to select for
a particular part of the page.
And if I say documen.queryselector*App,
that's going to mean find the thing
whose ID is app and render
the Hello component there.
So that's the basic idea.
We defined a class called |
that has a render
function that basically
says what should the
Hello component do when
I tried to render it to the screen.
And then underneath that, after
we finished defining the class,
we use ReactDOM.render to say,
let's take this Hello component
and actually render it.
And where are we going to render it?
We're going to render it inside
of this div whose ID is app.
So you could imagine if you add a more
complex page where you add other HTML
elements involved, you could just insert
some React code in one particular part
of your web page, for instance.
COLTON OGDEN: It's almost like it lets
us extend the very nature of HTML.
BRIAN YU: Yeah, exactly.
COLTON OGDEN: Bavick Knight says tags
are ended like image tag of HTML for--
I'm guessing he's referring
to your Hello tag.
BRIAN YU: Yeah, so the idea is that this
Hello tag, in some HTML tags like div,
for instance, we have both an
open tag like angle bracket,
div, end angle bracket, and then
an ending tag, slash div, to mean,
all right, this is the end of the div
with the content of the div in between.
With some tags like the
image tag, as you point out,
or like the Hello tag in this particular
case, we don't need to do that,
because it's not that there's any
textual or other information that we
need in between the start and end tag.
All of the information that this
Hello component needs in order
to render itself is already
inside of this Hello class.
COLTON OGDEN: I'm
guessing there are tags
that we could define they do allow
us to sort of put other tags nested
within other React tags.
BRIAN YU: Generally,
not too conventional.
In fact, what we would
likely do is add some
of what we would call props
to this react component
where we could pass
additional information,
but we would pass them
in the way we would
pass HTML attributes, for instance.
So we would say like, Hello, some
property is equal to some value,
for instance, which you could do.
But in this case, for a
relatively simple component,
we're ultimately not
going to need to do that.
COLTON OGDEN: Got you.
It looks like Elias says hello.
Elias is a regular.
Good to see you, Elias.
Div tag beneath the body
as well, ended on the line.
BRIAN YU: Yeah, exactly.
So this div right now is empty, and
so we didn't need a separate closing
tag because there was really
nothing inside of that so assuming
I did everything right, if
I now go back to my web page
and refresh the page, we see that now
there's Hello rendered on this web
page, even though I didn't
actually write Hello
into the div inside the body itself.
All I said was, if we
go back to this code,
to render this Hello
component inside of this div,
and the whole component knows
that it should just render
a div inside of which says, hello.
COLTON OGDEN: And that
will be reflected.
If you looked at the
page source, I'm guessing
it would just say div,
hello world, end div,
just like we literally
wrote in that component.
BRIAN YU: The page source itself
is going to contain the JavaScript.
So if we look at the page
source, for instance--
let me shrink this down a little bit--
we're going to see the same
JavaScript that we originally wrote.
COLTON OGDEN: Oh, I see OK.
BRIAN YU: But if you take a
look, most web browsers nowadays
support the idea of like, OK, let's
explore the HTML elements that have
actually been rendered to the page.
So if I control-click
and click on Inspect,
for instance, I could go to
the elements, open up the body,
and inside of the div
now you can see that we
do, in fact, have just a div
that says, hello, right there.
And so that's the result of
what's been rendered inside
of that particular application.
And you can see that right there.
COLTON OGDEN: OK, makes sense.
We have an ID equals App as well.
BRIAN YU: Yeah, there it is.
So that's how we knew where to put
that particular div into this web
application for now.
And so that was our
first React component,
a React component that allowed us
to add some interesting information
into this page.
What questions do you
have about that so far?
COLTON OGDEN: There will be like
probably a 10 or 15 second delay
as well, so if you want to continue,
I'll monitor the chat for you as well.
BRIAN YU: All right, sounds good.
So given that very basics, let's go
ahead and try and build something
a little bit interesting.
And what I thought
we'd do today is build
a game that uses React as a way
of exploring how to manage state,
about how to update the HTML
of our web page dynamically.
And so that's what we're
going to try and do.
We're going to build a game that is
akin to like a flash card type game.
I remember my younger
brother, for instance,
when I was trying to teach
him math for the first time,
and I would show him flashcards.
I've got 1 plus 1.
What does that mean?
OK, he would say 2.
Show him another flash card, 2 plus 3.
What is that?
And so we're going to build this
like addition flash card game.
We're going to see what's something
plus something up on the screen.
There'll be an input field
where you can type in an answer.
If you get it right, you
move on to the next question.
If not, you have to try again.
And maybe we'll keep
score too, eventually,
just to keep track of that information.
And we're going to do all of
that using the power of React.
So that's ultimately where
we're going to be headed.
And so let's try this out.
Instead of a class called Hello,
let's go out and call this class
App, because it's going
to be our application,
but it could be called anything.
And instead of rendering
a component called Hello,
we're going to render
a component called App.
And inside of this render function,
let's go ahead and render,
and I'm going to put this in
parentheses just because I'm
going to probably take
this on in multiple lines
just for clarity's sake,
though technically you
could put it onto one line.
It's often conventional if you've got
a lot of HTML just to space things
out, the same way you
would space out HTML even
if you weren't using react to do it.
And so instead of saying
Hello inside of my code,
I'm going to instead
try to find a question,
like an addition question,
something plus something else.
And so let me create a div where
that question is going to go.
And for now, I can just say
something like 1 plus 1.
I'm going to give this div an ID.
I'm going to call it Problem
for now, just because later I
want to do some styling or
reference this particular div
at some point in time.
But right now, it's just going
to be a div whose ID is problem,
and right now it's just going
to say, 1 plus 1, for instance.
If I go back to the web page and
refresh that, instead of hello,
I now see 1 plus 1.
So here's the interesting thing.
It's not actually going to be all
that easy now inside of this 1 plus 1
if I ever want to
update the problem, if I
want to update it to be 2 plus
2, 3 plus 5, for instance,
because I'm going to
need to find this div
and update the contents of
this text to be whatever it is
that I want the numbers to actually be.
And so one of the philosophies of React
is that everything belongs in state,
or our components have
this idea of state,
where for any given component, anything
that determines any information that it
wants to store that
could potentially change,
you can put in something called
the state of the component,
and then your HTML inside
of the render function
can reference that state in
order to decide what to display.
So what I want to do here
is not say this is 1 plus 1,
but I want to store these
numbers in some kind of state
inside of my component such
that later on when I render it,
I can just say rather
than 1 plus 1, let's
draw this information from
the state of my component.
That way, if ever update the
state, my web application
will also update as well.
So for now, it's going
to seem like we're
doing more work than we need to because
we're going to add extra code just
to get the same 1 plus 1.
But we'll see down the road when we want
to change the problem, for instance,
or when we want to verify that the
user got the answer right, that having
this these numbers stored
inside of the application state
is actually going to
be very, very helpful.
COLTON OGDEN: It's like declaring
variables for our application.
BRIAN YU: Yeah, exactly.
It's using variables for these numbers
rather than just writing the number 1
hardcoded into the HTML
of the page itself.
So to do that, what I'm going to
do is inside of a JavaScript class,
I can define what's
called a constructor.
And the constructor is what's
going to run when I first
create an app, when I
first try and create an app
and put it into my web application.
It's taking this argument called props.
These are just additional
properties that
can be used to modify what it is
that this component looks like.
We're not going to use these props
too much for the sake of right now,
but certainly they're a very
powerful feature of React,
and are especially helpful when you're
nesting components within themselves.
But the first thing we're
going to do is, just
because this is a class, it's
extending from react.component,
I technically need to
say, super props, meaning
let's let the superclass, the component
itself, initialize itself as well,
call it its own constructor class.
But the interesting
stuff that I want to do
is set the state, this.state of
this particular reactor component.
And this.state is going to be a
JavaScript object, so a bunch of keys
and values, that are
going to define what
it is that's contained within the
state of my react application.
So what are the things
that are right now
in the state of my react application?
Well, in the state of this game of
showing numbers and typing in results,
at minimum I need two pieces of state,
one to represent each of the numbers
that I want to display
on my web application.
So I'm going to call those Num1
and I'm going to call it Num2.
And by default, each one
of them is just going
to be 1, such that the first thing
that gets displayed on the page
is just going to be 1 plus 1.
Num1 is going to be the state of the
first number in the pair of what's
being added.
Num2 is going to be the second one.
All right, so we've defined
the state of the application
there in the constructor,
and now what I need
to do inside of the render function,
rather than just say 1 plus 1,
I instead want to draw
from Num1 and Num2
inside of my state to decide
what it is that my application is
going to look like.
So instead of this 1, I'm going
to insert a JavaScript value here.
And to do that in React, we're going
to use the curly brace syntax to mean,
insert some variable here.
And the variable that I want
to insert is this.state.
And which part of the
state is the first number?
Well, it's just called Num1.
That's what I defined up on line 17.
So I have this.state on Num1, which
is going to take Num1 from the state
and just insert it right there in
the HTML code for my web application.
COLTON OGDEN: It's almost like
using a templating language.
BRIAN YU: Yeah, it's very
similar to a templating language
if you've used things like Jinja, for
instance, along with Flask or Liquid,
for instance.
Very similar in spirit.
COLTON OGDEN: We have a
couple of comments there too.
Pick 9117 says the target audience of
this channel are not used to NPM yet.
It's going to kind of vary.
I think we likely will
go into a lot of videos
in the future that are for
people that are used to NPM,
but I'm assuming that today's video
relies on no prior knowledge of NPM.
This is more of a--
I mean, I guess you can
develop React with NPM,
but I think this is just
like a from scratch tutorial.
BRIAN YU: Yeah.
In fact, it is probably more
conventional to design React apps using
something like Node
and NPM, for instance,
in order to manage your packages.
We're doing it this way in
just a static HTML file for now
just to make it easy to follow for
people that don't have that installed,
for instance.
But if you are interested in the
probably more conventional way
to do this, take a look
at Create React App,
which is a way of just creating
a sample react app just
from scratch that uses
NPM, for instance,
in order to install and manage
dependencies and packages.
That tends to be the way that
people will conventionally
start building a React front
end nowadays if they want to.
This just happens to
be another way to do it
that's a little bit simpler if you don't
have that background, for instance.
COLTON OGDEN: [INAUDIBLE].
Nuanda 3333.
You explain everything thoroughly.
Thanks a lot for that.
Easier to follow.
BRIAN YU: I'm glad you're
finding it easy to follow.
React can definitely be challenging at
times, so not to worry if some of this
seems complicated.
There are a lot of resources
out there available
on the internet to help you out there.
COLTON OGDEN: And Bavick
Knight wants clarification.
So super is the react.component,
right, the superclass?
BRIAN YU: Exactly.
The react.component is the superclass,
and so super refers to that.
Precisely.
COLTON OGDEN: Awesome.
BRIAN YU: All right, so we've extracted
the first number from the state
and put it in the first
part of the addition.
And as you might guess,
the analog here is
with the second number in this
addition problem, this plus 1,
rather than the other plus 1.
I'm going to say this.state.num2.
So now instead of hard coding 1 plus 1,
I'm saying extract Num1 from the state
and then do plus, extract
Num2 from the state,
and we're going to display that instead.
So now if I go back to the
page and refresh the page,
you'll notice it stayed the same.
Nothing changed.
We added a whole bunch of code and
we didn't see any noticeable result.
But the idea here is that
now these numbers 1 and 1
are being drawn from the
state of my component
rather than just being hardcoded
into the HTML of the page,
such that later on, if I
were to change the state,
if I change Num1 to be 27 for instance,
and I save that and I refresh the page,
now it's, OK, 27 plus 1.
Just by updating the state,
I've been able to update
what it is that the front
end of my web application
is ultimately going to look like.
COLTON OGDEN: I'm guessing you can
make a component that takes input 2
and then changes the
state as a result of that.
BRIAN YU: Yeah, certainly.
So if you want a component that
takes the input right at the start,
that's generally done through
the props of that component,
and so you can do that as well.
So all right.
We've defined this problem, and
it's going to define Num1 plus Num2.
And now we also need some place where
we can begin to type in the answer
to this.
So underneath this div, let
me define an input field.
And this input field, right
now I'm just going to say,
OK, it's just an input field.
That's it, where the
idea is going to be this
is going to be the place where
the user playing this game
is going to type in the answer to
this addition problem, for instance.
So if I refresh the page after
adding that input field, here it is.
Here's my new game.
I've got 1 plus 1 up at the top,
and I've got this input field down
at the bottom.
COLTON OGDEN: Can you read that last
comment there in the Twitch chat?
BRIAN YU: 10 plus 1.
So anyone who wants
to know what 10 plus 1
is, it's a joke for people that have
been keeping up with CS50's lectures
here on campus for fall 2018.
The 10 plus 1, it comes
up at one point in time.
So if you haven't seen those lectures,
you might-- oh, that's David.
COLTON OGDEN: Shout outs to [INAUDIBLE]
for joining us on Twitch today.
You can read that last
one too, if you want.
BRIAN YU: What configuration software
do you use to record the video?
[INTERPOSING VOICES]
COLTON OGDEN: So we use
Streamlabs OBS software.
We have a full production setup.
Mr. Dan [INAUDIBLE] is
actually here in the studio.
Now, do you want say hi on camera, Dan?
Our cameraman, our production staff.
SPEAKER 3: Hello.
COLTON OGDEN: Actually, why
don't you answer the question?
What do we use to record the
video besides Streamlabs.
SPEAKER 3: The camera
we're using is a Sony A7S
with a Canon [INAUDIBLE]
millimeter mark 2 lens, I believe.
We have a PC with the streaming
software set up, which you talked about.
And otherwise, we have some
simple lights hanging up
on that green screen in the back.
Pretty simple setup.
COLTON OGDEN: And what are you going to
be on here next Tuesday to talk about?
SPEAKER 3: Next Tuesday, join us for a
little bit of Paper.js, and maybe some
Hammer.js as well, the
underlying components of Draw 50.
Should be fun.
COLTON OGDEN: Nice.
Yeah, the software that David uses
to actually draw in the lecture,
like a digital chalkboard, so.
SPEAKER 3: And I'm here just to check
on Brian's microphone, so excuse me.
COLTON OGDEN: Oh, OK.
Hopefully we didn't screw it up.
BRIAN YU: Working OK?
All right, sounds good.
All right, so we now have this
these two numbers, 1 plus 1,
and plus an input field where I
can begin to type what I think
is the answer to this problem.
And so at this point, we
have a new piece of state
that we want to keep track of
inside of this web application.
In particular, we want to keep track of
what it is that the user has typed in,
because that's technically part
of the state of the application,
but part of the state of this component
is knowing what the user's typed in,
because ultimately we're going to
want to check that against whatever
the actual answer to
the addition problem is.
So let me go ahead and add something
to the state of this application.
In addition to keeping track of Num1
and Num2, the two numbers that I'm
going to try to add, I'm also
going to add to the state
a response, which is going to start
out being the empty string meaning
by default, there should be nothing
in the input field, no response.
But this response is going to
be the part of the state that
keeps track of what it is
that the user has actually
typed in into this input field.
And now I'm going to go
down to this input field,
and I'm going to say that
the value of this input field
is going to be this this.state.response
In other words, whatever
it is that is inside
of this.state.response,
that is going to be what gets
filled in into the input field.
So now if I refresh the page,
1 plus 1 plus the input field,
nothing's changed just yet.
There's nothing in the input field
because the response by default
is the empty string.
But if I wanted to change that,
for instance, if I went back here
and I changed the response
to be like Hello by default,
for instance, and refresh
the page, well now, OK,
hello shows up in the input field
because whatever this.state.response
is, that's what gets filled
in into this input field.
But it should be empty
just to begin with.
An interesting side
effect is, and maybe you
won't be able to tell this because
the keyboard's behind the camera,
but I'm going to try
typing something right now.
I'm going to try and type numbers,
and what Colton at least can notice
is that as I'm typing
numbers, nothing is actually
showing up in the input field.
COLTON OGDEN: Verified.
BRIAN YU: Yeah, and so this seems like--
COLTON OGDEN: He's not lying to you.
BRIAN YU: A little bit
of a strange thing,
as you might expect, right, input
field, I start typing things into it.
Things should start appearing,
but nothing's appearing.
The input field is still
blank, and so that's
sort of a strange quirk of React.
Why might that be?
Well, it turns out if we look back
at the code, look at what we've said,
we've said whatever is contained inside
of this.state.response, that should
be what shows up in the input field.
And this .state.response is
always just the empty string.
It never changes.
We've never changed what it's equal
to right here, and so as a result,
we're always seeing the input field as
blank no matter what we try to type in.
And so what are we going
to have to do here?
Well, we probably want
some notion of, all right,
whenever we try to change
the value of the input field,
let's go ahead and update this
.state.response to reflect whatever it
is that the user's
actually just typed in.
So let's do that.
In this input field down here,
I'm going to say, onChange.
And notice the capital C just
happens to be a React convention,
so onChange with a capital
C is how we're going to say,
when the input field's value changes
and then I try to type something
in, for instance, let's go
ahead and call a function.
And what function do I want to call?
I'm going to call it
this.updateresponse.
It could be called anything, but Update
Response feels like a reasonable name
to give it just for now.
Now what is-- I haven't defined Update
Response yet, so let me go ahead
and do that.
Down underneath the render function,
let me define an Update Response,
which is going to be equal to--
and here I'm going to use an ES6,
the latest version of JavaScript
specific feature, known as
arrow functions, which are just
another way of defining
what a function is,
and I'm saying that this is a function
that's going to take in as its input
the event, the event of me actually
typing something in, trying
to change the value of the input field.
And when I get that input of the
event, here's what I'm going to do.
So the arrow is saying
the input is the event,
and here is the body
of the function itself.
And now here is what I'm going to do.
I'm going to update the
state of my application,
and to do that, React has a special
function called this.setstate.
And I'm going to set the
state, and in particular, I'm
going to set the response
equal to something.
Remember, response is the
part of the state that
corresponds to what
the user has typed in,
and in JavaScript, what you may
or may not be familiar with,
the way to take an
onChange event and extract
the thing that's
actually been typed in is
to set it equal to event.target.value.
The event is the actual change event.
I tried to change the
value of the input field.
Its target is, OK, what
was I trying to change.
It was the input field.
And what is that input
field's value, meaning
what did I actually try to type in?
That's going to be the thing that I
should update my response to be now.
COLTON OGDEN: Gossen says, why do
you talk about states whereas you
have likely declared variables
just like the response variable.
What's the meaning of the word state?
BRIAN YU: Yeah, good question.
So state you can think of
as sort of like a variable,
but before React and before
the React-like user interfaces,
if I had some state, some variable,
that was keeping track of information
about my application, and I wanted that
reflected inside of my actual web page,
I would need to first
update the variable,
update my state, so to
speak, and then also run
a command that would actually
take the value of the variable
and like update the HTML.
So you might be familiar with like
updating the inner HTML of an element,
for instance, if you've
use JavaScript before,
like take the value of a variable and
put it inside of a particular HTML
element, for example.
What React is going to
allow us to do is not
need to worry about any of
that, where the idea is going
to be our interface is going
to update itself dynamically,
reactively, based upon the state.
So the idea here is that on
line 35, when I set the state
and update what the
value of the response
is, that's going to result
automatically in my user interface
updating what value is in the input
field without me needing to say,
all right, grab the input field,
let me update the value there
and insert something there.
Everything is just going
to respond to that state.
And you might imagine that in a more
complicated user interface, where
multiple different parts of
your user interface dependent
upon the same piece of state,
it becomes a whole lot easier,
because you update the state once,
and anywhere in the user interface
where that user interface is
dependent upon that piece of state
will update automatically.
And so we'll see examples
of this, and you'll
start to see how this is powerful
as we continue to build out
this particular application.
Good question, though.
COLTON OGDEN: Bavick also said input is
like setters I guess, using a setter.
BRIAN YU: Input in this case
is just an HTML element.
So when we're describing
the structure of a web page,
we can use HTML elements like div
to define a particular section
of the page, an input in this case, to
mean this is a part of the HTML page
where we can begin to type
something in, for instance.
So all right.
We just added this update
response function that gets
called whenever the
input field is changed.
Let me go ahead and go back
here, refresh the page.
Nothing seems to be different, but now
if I try to type something in, 1 plus 1
is 2.
All right.
Great.
Now when I typed it in, that
updated inside of the state
what the response is, and
we're seeing it right there.
And in fact, I can prove this to you
that it's actually updating the state
and showing the response by
adding a little bit of extra code
that I'm going to
delete in just a moment.
But let me add another div where I
say, for instance, that the response is
this.state.response, where I'm
just effectively printing out
what the current value
of this.state.response
is right now, for instance.
COLTON OGDEN: Twitch Hello
World says, thank you
for starting with a static site.
Is there a book that covers this
to refer to later, by chance?
BRIAN YU: A book that covers this.
I wouldn't necessarily recommend
or refer you to a particular book,
because libraries like
React are always updating.
React is constantly being updated
with new features, features
that are coming and going, and so by
the time that a book is published,
odds are that a lot of the
things that are described in it
are already going to be out of date.
But there are a lot of online
resources with regards to React.
You can look to Facebook's own React
documentation for a lot of tutorials
and guidance on how to
do this sort of thing,
and many other people
out there on the internet
have also put out tutorials for how
to do particular things with React,
so a lot of great online
resources there even if there
aren't any good books on the subject,
at least not that I'm aware of.
COLTON OGDEN: Probably a
lot of YouTube videos too.
BRIAN YU: Yeah, I'm sure
plenty of YouTube videos.
COLTON OGDEN: The blue's
a little bit hard to read,
but it's Andre Pedalin, who's on
our Facebook if you're familiar.
BRIAN YU: Oh, yeah.
Yeah.
COLTON OGDEN: He says,
hi, Brian and Colton.
So the argument to this set
state is the JSON object?
BRIAN YU: Yeah, you can think
of it like a JSON object.
Really, you can think of in this case as
specifically a JavaScript object, which
looks very much like a JSON
object would look in this case.
So all right.
I've added this response
is this.state.response,
and now you can really see what I mean.
Right now, response is nothing, but
if I start to type something like 2,
my user interface is automatically
updating anytime I type
or remove a character,
because whatever I type in
is becoming part of the state.
And because whatever after
its response is is just
referencing that state,
whenever the state changes,
my web application is updating
dynamically in response to it as well.
So I'm going to get rid of
that because I don't actually
want that in the
application, but that's just
to show you this.state.response
is actually updating
anytime my input field is changing.
So all right, I'm on my way to
starting to build this game.
I'm able to see a math problem now.
I'm able to type an answer.
And what I'd like to do is,
you know, when I press Return
or Enter on my keyboard,
I'd like for that
to mean like, OK, submit my answer.
But right now I'm pressing
Return and you know,
nothing's happening right now.
So let's add a new event handler.
Let's handle the case when
the user presses the Return
or Enter button, and do something
interesting in that case.
So go back here.
In addition to input onChange, let
me add one that says onKeyPress.
In other words, whenever I press a key.
There's no particular event for pressing
the Enter or Return key specifically,
but there is an event for
saying when I press a key.
And what I'm going to do is,
so again, when I press a key,
let me check what key I pressed,
and if that key is the Enter key,
then let me go ahead and
do something interesting.
So onKeyPress, I need a function here.
I'm going to call it
this.inputKeyPress, for instance,
but I could, again, call it anything.
And let me now define that function.
The input key press is going to be
a function that takes an event as
with before, and first does a check.
If the event.key is equal
to Enter, well then that
means the user pressed the Enter key,
and I should do something interesting
now in response.
So what am I going to do?
Well, let me first actually get
what the user's response is,
and to save that instead of
a variable called Answer.
And I'm defining it as a const,
meaning a constant variable,
meaning this variable
is not going to change
at least for this particular
invocation of the function.
And it's going to be equal to--
well, where is the user's answer stored?
Well, what the user typed in, that's
stored in this.state.response.
But there's a small nuance here in
that what the user types into the input
field is a string.
It's text that the user's
typing into that input field.
And the answer to an additional
problem shouldn't be text,
it should be an integer.
And so I want to, in
JavaScript now, take this text,
covert it into an
integer, and the way I'm
going to do that is by using a
function built into JavaScript
called parseint, which is going to
take in this case this.state.response,
and it's going to convert
it into an integer.
I see that someone's a little bit
confused about the triple equal sign
and what that means.
This has to do with JavaScript
equality, that there are technically
a lot of things that could be equal
to each other by a double equal signs,
even if they're not strictly
speaking equal to each other.
The triple equal sign is
going to strictly check just
to make sure that they're equivalent.
In this particular case,
double equal sign probably
would have worked just fine, but
convention in JavaScript or good design
practice is, when you can use the
triple equal sign, indeed to do so.
So I've defined this
variable called Answer,
which is what it is that the user
has typed in to the input field.
And now what I want to do is, I
want to check to see whether or not
the user got the answer right or not.
Did the user get the answer right?
And so how might I check that?
Well, all right.
I'm going to run an If condition.
I want to check if Answer is
the sum of the two numbers
that are in the problem.
And now where were the two
numbers in my problem stored?
Well, if we think back, it was
really stored in this.state.num1,
and I want to check if Answer
is equal to this.state.num1 plus
this.state.num2.
In other words, did
the user correctly get
an answer that was the
sum of the two numbers
that were presented as
the problem on the screen?
And so if the answer was correct,
well, what do we want to do?
Well, what I want to do is I want
to set the state of my application,
and I want to give them a new problem.
I want to give them a
new Num1, and I want
to give them a new Num2 because
they got the answer right.
Let's give them a new
problem to work on.
So in this case, I'm going to say,
all right, Num1 is going to be what.
Well, I want it to be some
random value, and so JavaScript
has a function called math.random.
Math.random is going to get me
a random number between 0 and 1.
Probably not too interesting if those
are the only numbers I'm dealing with,
so let's deal with things
a little bit bigger.
If I do math.random
times 10, that's going
to give me a random number
between 0 and 10 or 0 and up to,
but not including 10, for
instance, in this particular case.
So I've got a random number, but this
could be a floating point number.
I might get something like 3.
In fact, I probably will.
There's something like
3.28574 something something.
But what I really want, this is just
going to be a beginner's edition flash
card program, is not to have
this be a floating point number,
but for it to be an
integer, for instance.
And so the math operation
I'm going to use here
is math.ceil, meaning
math.ceiling, and the ceiling
of a number that has a decimal is
just take the next highest number.
So if the number is
3.28, the ceiling of that
is just going to be, take the next
integer that's higher than that,
in this case, 4 for instance.
And so this is going to get
us a number from 1 to 10,
for instance, just some
randomly chosen number
that we want to be the next Num1.
COLTON OGDEN: [INAUDIBLE]
says, the triple equals
is because JavaScript
is three times cooler.
Can you verify that that's true?
BRIAN YU: You know what?
I wasn't the person who
designed the triple equal sign,
but maybe that was part of it.
Who knows?
Num2, meanwhile, is going
to be the same thing.
I also want it to be a random
number between 1 and 10,
so I'm going to set it to be the
ceiling of math.random times 10.
This is a conventional way,
not just JavaScript specific,
but oftentimes programming
languages will give you
a way of getting a random
number between 0 and 1,
when realistically what you want is
a random integer in some other range.
And so knowing how to do
the multiplication and maybe
addition in order to shift your random
floating point number between 0 and 1
to the range that you want
is often a useful trick
to be able to use if you want
to generate a random number.
And so this is what I'm going to do.
If the answer is correct, then update
the state of my web application.
Update Num1 to be some
random number, and update
Num2 to be some random number as well.
So let's give this a try.
Assuming I did everything
right, I'll refresh the page.
We have 1 plus 1.
If I get the answer wrong, if I type in
3, for instance, then I press Return,
well, all right.
Nothing happens.
And that's to be expected, right.
Nothing happens because what I typed in,
3, is not correctly the sum of 1 and 1.
But if instead I type in 2, which is
the correct answer, and I press Enter,
watch what happens, hopefully.
All right.
I press Enter and the problem changed.
It changed to 8 plus 1.
COLTON OGDEN: If that changed back
to 1 plus 1 again out of randomness.
That would have been fun.
BRIAN YU: It would've been possible for
it to change back to 1 plus 1 randomly,
but in this case, it did in
fact change to something else.
It changed to 8 plus 1 by generating new
random numbers in this particular case.
So why did that happen?
Well, if we go back to the code,
when the input key was pressed,
we check to see if the
key was the Enter key.
It was.
We calculated what the answer is
by taking what the user typed in,
passing it as an
integer, in that case 2.
We checked to see if the answer was
equal to the sum of the two numbers.
2 is equal to 1 plus 1.
Yeah, it is.
And since it was, we updated the
state to reflect two new numbers.
Now there's a user interface
suboptimality here,
something that's not quite great about
the way this user interface works.
And I'm sure that you saw
it if you saw me do it.
I'll do it again if I try
and get this answer right.
If I type in 9, getting the
answer right, and I press Return,
I get a new problem, but in my
input field, the 9 is still there.
Probably not what I want, because
probably I want an opportunity now
to type in something new.
So how do I fix this?
Well, in reality, this
becomes pretty simple.
This 9 is only there because 9 is the
current value of this.state.response.
It's the current value of the response
inside of the state of my current React
component.
And so if I want to clear out the text
field anytime the user gets the answer
right, well, let me go ahead and say,
all right, Num1 gets a random number.
Num2 gets a random number.
But let me also update
the state's response,
and just set it to be the empty
string again, in other words,
clear out the response if
the answer is incorrect.
COLTON OGDEN: Do you want to
start about halfway down the chat?
Twitch Hello World has
a question for you.
BRIAN YU: Yeah.
Let me show this real quick and
then we'll answer the questions.
So if I refresh this now, 1 plus
1, I type in the correct answer, 2,
and when I press Return, I get a new
problem and the input field clears out.
So much better user interface from the
perspective of the person using it,
because now you can actually type
in another answer, press Return
and you get a brand new problem.
And so that's definitely
a whole lot better.
COLTON OGDEN: We shouldn't
show this one to David.
He probably wouldn't get it right.
BRIAN YU: All right.
Twitch Hello World
asks, does math.random
generate a pseudorandom number.
Yes, math.random generates a
pseudorandom number between 0 and 1,
and that's the way most random number
generators ultimately are working.
COLTON OGDEN: And Nuanda says,
aren't they all sort of random.
Andre, I think he's
making a point about being
able to visually see the difference in
double equal and triple equals, which
you do in a terminal.
BRIAN YU: Yeah.
We can show this right now,
actually, if people are curious.
If I go into the
JavaScript console and I
can just open up the
inspector to see it.
COLTON OGDEN: Turned the
chat off there for you.
BRIAN YU: Oh, yeah.
Great.
Thank you.
If I do something-- what
is the example there?
If I do 1 equals equals the
string 1, press Return, all right,
that's technically true.
So you can see this double equal sign
is doing a bit of a loose equality.
Yeah, 1 is basically
the same thing as 1,
and it's a little more flexible
in what it counts as equality,
whereas this triple equals
is a strict equality.
Is the integer 1 equal to this string 1?
Well, that's ultimately
going to be false,
because no, those are different things.
One of them is an integer.
One of them is a string.
You can likewise see this if I check, is
0 double equal to false, for instance.
That's true.
0 and false are both falsey values
in the world of JavaScript, so
double equal sign,
those compare as equal.
But 0 triple equal sign
false, for instance,
that's false, because the
number 0 is not strictly equal
to the Boolean value false.
And so the triple equal sign gives us a
slightly different result, and so just
for precision's sake, I'm
using the triple equal sign
where it's appropriate to do so.
COLTON OGDEN: Would you
say this flexibility
is a reason for some of the
weird sort of type coercion bugs
that are topics of like the
[INAUDIBLE] talk for example?
BRIAN YU: Yes, definitely.
You should definitely go
take a look at those talks
if you haven't already
seen it, but it's amazing
the things, the sort of strange
features of the JavaScript type system,
where because of the way
the type system works
you can get it to behave
in very strange ways
that you might not initially expect.
But definitely some funny talks
out there about that subject
if that's something
that's interesting to you.
COLTON OGDEN: Twitch Hello World.
I heard there is no such thing in CS as
genuinely a true random number, though,
Haven't verified exactly.
That's correct, right?
BRIAN YU: Yeah.
Computers can really only do, can
only follow the instructions that they
are given, and so really what
ultimately happens in order
to generate a random number
is that the computer is doing
a whole bunch of mathematical operations
to generate a number that feels
random to us, and that follows the
expectations of a random number,
like it will be distributed
randomly across a range.
But that ultimately might
not actually be truly random,
and the question of
what truly randomness is
is an actually really interesting
question, not only in computer science
but in math and philosophy as well.
The technical term for
that is stochasticity,
so feel free to look into that if that's
something interesting to you as well.
COLTON OGDEN: Meal Eagle looks like
he has a question addressed strictly
to you if you want to read that one off.
BRIAN YU:
SPEAKER 3: Yeah.
Is it more user friendly if
you enter an incorrect answer,
there is a visual indication
that you got it wrong?
Great question.
That is definitely the case, because
right now if I get an answer wrong,
10 plus 9, if I think the answer is
11 for instance, and I press Return,
nothing happens, and that's probably
not the best user interface.
So definitely improvement that we can
make there, and in a couple minutes
we'll go ahead and make
that improvement just
to make the interface a little
bit better if the user does,
in fact, get the answer
wrong in this case.
COLTON OGDEN: Gossen says, in
case of a non-integer input,
does the instructions
throw an exception,
because frankly, I see that it's
based on Java philosophy just taking
advantage of the web scripting.
BRIAN YU: Yeah, good question.
So if I type in a text,
like hello, for instance,
you'll notice that nothing quite
happens, and that is a good question.
So it looks like it's never going to be
the correct answer if you type in text,
because the answer is not going
to be equal to Num1 plus Num2.
I can't remember exactly
how parseint is handling it.
I actually thought it was going to
throw an error, but interestingly--
COLTON OGDEN: You could probably
console, parsing it hello.
BRIAN YU: Yeah, that's a good idea.
Parse it hello.
It returns NAN, which stands for not a
number, which is what you might expect.
COLTON OGDEN: The Batman
part of the [INAUDIBLE] talk.
BRIAN YU: Indeed, yup,
if you're seen that talk.
And indeed, NAN, not
a number, is not going
to be equal to the sum
of these two numbers,
so it's actually fine in this
case to just use parseint.
Good question.
COLTON OGDEN: And Bavick Night
says, Java is weird as well.
String 1 plus 1 is 11 with the
default string concatenation
being the plus operator.
Twitch Hello World, I might
not remember accurately,
but I thought you said a number
less than 10 would be generated.
Did you change this in the second step?
I thought maybe the pseudorandom number
generator was between 0 and 1, maybe.
BRIAN YU: Oh, question.
So yeah, it's not going
to generate the number 10,
but it could generate a
number like 9.5, for instance.
And if it generates 9.5, and then I take
the ceiling of that number right here
in math.ceil, the ceiling of 9.5 is
ultimately going to bring 9.5 up to 10,
and so that's how I'm able to get a
number ultimately between 1 and 10
in that range.
COLTON OGDEN: Looks like Bavick just
chimed in with that same detail there.
BRIAN YU: Yup.
Good observation.
COLTON OGDEN: Awesome.
BRIAN YU: So all right.
I forget, it was Metal
Eagle who mentioned it.
The way that we handle an
incorrect answer right now
is not ideal, right, because right
now, if I enter an incorrect answer, 10
plus 9, I type in 11 for instance,
I press Return, nothing happens.
So what should happen?
Well, I feel like at minimum, we
should clear out the response field
just as we did before to
give the user an opportunity
to try again, for instance.
So let's do that.
If the user got the answer right, then
we're setting the state, but else,
if they got the answer wrong, well,
let's do something interesting
there too.
Let's say this.setstate,
and let's just for now
set the response equal
to be the empty string.
In other words, clear out
the response, because we
want to clear out the input
field such that the user can now
type in some new answer.
So go ahead and run
this application again.
1 plus 1.
I type in 2.
I got that right.
9 plus 8, let's say I struggle
with this a little more.
The correct answer is 17, but
instead I typed 16, for instance.
And I press Return.
Input field clears out, but
I don't get a new problem,
because I didn't update
Num1 and Num2 in this state.
Those are still the same
thing, and just clearing out
the input field such that now I can
actually type in the correct answer,
press Return and get
a new problem there.
COLTON OGDEN: We need like
a really obnoxious buzzer
sound when you get it wrong.
BRIAN YU: Yeah, so we
could add sounds in,
a little bit fancier than we'll
do here, but I think at minimum we
can do some UI improvement.
Like if I get the answer wrong, right
now it clears out the input field,
but maybe let's try and say, let's
get this problem field to turn red,
for instance, when I
get the answer wrong,
because that might be a visual
indication that all right, I
got the answer wrong.
Input field cleared out
and the text turned red.
So let's try and do that as well.
So now how am I going to
go about implementing this?
Well, the first thing to
realize is that whether or not
the user got the answer
wrong, that's going
to be part of the state of my
application, you might imagine,
that by default I didn't
get the answer wrong,
but you might say later
on, if I do get the answer
wrong, that's going to change
the state of my application
because I want my UI to reflect the fact
that the answer was wrong by turning
the text red, for example.
So up here, when I
initially define the state
of my application up in the constructor,
let me add a new part of the state
that I'm going to call like, Incorrect.
Did the user get the answer incorrect?
And when the game first starts, they
haven't yet gotten anything incorrect,
so Incorrect by default
is going to be false.
So all right.
Now when the user gets an
answer wrong, in addition
to setting Response to be
equal to the empty string,
let me also set Incorrect
to be equal to true.
I'm updating the state such
that this Incorrect value is now
going to be equal to true.
Now, how am I going to
style the web application?
I'm going to turn the text read
if the user got the answer wrong.
COLTON OGDEN: My first
inclination would be CSS.
BRIAN YU: CSS is a great
inclination, actually.
In fact, let's try this right now.
What you might do is up here,
in my application in the header,
I might define some style, and you might
want to move this to a separate file
just to separate things out.
But for the sake of example here,
we'll just put it in one place.
And maybe let's define a
class called Incorrect.
And the dot in CSS means if
something has a class of Incorrect,
well, let's go ahead and change
the color to red, for instance.
And that might be what we do.
If something has a class of Incorrect,
the color is going to be red.
And we can test this now.
If I go down here to my problem where
I have Num1 plus Num2, and I say,
let's give this ID a
class, and in React,
because the word class is
already used for like Class app,
the way we define a class using React
is to call it a class name, technically.
And let me set class name equal to
the JavaScript string Incorrect.
So if I set the class
name to be Incorrect,
plugging in the
JavaScript string there--
COLTON OGDEN: And a question.
Why is it in curly brackets there
instead of the like ID equals?
BRIAN YU: Because I'm inserting
a JavaScript value here.
It'll be clear in a
moment why I'm doing that.
Now if I refresh the page, we see
that the text has indeed turned red.
We get 1 plus 1 in red there.
Is that showing up on the--
COLTON OGDEN: It's red, yeah.
Yeah.
BRIAN YU: It is red?
OK.
It shows up on my
screen as red, at least.
COLTON OGDEN: TV color isn't
the greatest, I don't think.
BRIAN YU: Oh, OK.
So 1 plus 1 is red, which works.
I was able to use CSS now to change
the color of the text of the problem,
but this isn't quite right, because
1 plus 1 is red from the get go,
and I only want it to be red if
the user got the problem wrong.
So what I'm going to do here,
I'm going to use some JavaScript
logic here inside of the class name.
In other words, I don't want the
class name to always be incorrect.
I only want the class name to be
incorrect if the user actually
got the answer wrong.
In other words, if the Incorrect
part of the state is equal to true.
And so to do that, I'm
going to use what's called
the ternary operator in JavaScript.
It's very similar to the
ternary operator in C or Java
if you've used it in other languages.
But basically, I'm going to ask myself
the question, this.state.incorrect, did
I get the answer wrong?
Is the value of Incorrect
in the state true?
If it is Incorrect, if the
user got the answer wrong,
then the class should be
Incorrect, but otherwise, we'll
go ahead and just use the empty string.
In other words, don't
give it a class name
if the user didn't get the answer wrong.
COLTON OGDEN: Makes sense.
So any time you use curly
brackets, basically if you want
to do any sort of programming logic.
BRIAN YU: Exactly.
Any JavaScript programming logic,
that's going to go in the curly braces.
And so here I'm adding some
logic saying, don't always
give this div this class of Incorrect.
Only give it that class if
the answer is in fact wrong.
And so let's see what
the result of this is.
I refresh the page.
1 plus 1 shows up, and 1 plus 1 is in
black text, which is to be expected.
If I get the answer right,
input field clears out.
I get a new problem.
Same thing if I get it right
again, input field clears out.
2 plus 5, the answer is 7.
But if I get it wrong, if I type in
8 for instance, and I press Return,
watch what happens.
Two things happened.
Input field cleared
out, and the text now
turned red because I updated the state.
Incorrect is now true, and as a result,
this div gets that class of Incorrect.
And according to my CSS code,
that's going to style it as red.
COLTON OGDEN: And so now
if you get it right again.
BRIAN YU: Now, OK, so
here's an interesting bug.
If I get the answer right, I type
in 7, what's going to happen?
Well, this is the right answer.
I expect myself to get a new problem.
I expect the input field to clear out.
I expect the text to turn black.
I press Return.
COLTON OGDEN: Oh, it didn't clear.
BRIAN YU: It cleared out and I got a
new problem, but the text stayed red.
It's still red.
It still thinks I got the answer wrong.
Why is that?
Well, it's red based on the
value of this.state.incorrect,
which starts out as false,
and we set it to true
down here if I get the answer wrong.
But in particular, we never reset
it if I get the answer right,
and so this is where the bug is.
So when I get the answer right,
I want to also say, all right,
now the answer is no longer incorrect.
Incorrect is false.
We can go ahead and show
up the text as black again.
Yeah, exactly.
So I'm going to refresh
the page, get 1 plus 1.
I get the correct answer,
2, get a new problem,
get the correct answer
again, get a new problem.
If I get the answer wrong, type in 7 for
instance, press Return, all right, text
turns red now, and the
input field's cleared out.
But if I get the answer right again,
now I get a new problem and the text
turns back to black, so
that's what I expected it to.
COLTON OGDEN: Twitch Hello
World says, thank you so much.
I have to see the rest later.
I have to run.
Thanks, Twitch, for joining us.
I'll catch you next time.
Catch you on Friday, hopefully.
BRIAN YU: Yeah, thanks for joining me.
All right, so at this
point in time, we've
got a pretty functioning web
application at this point.
We have a user interface where
we display a problem that updates
dynamically, that generates new random
problems every time the user gets
the answer right, and if the user gets
the answer wrong, our UI reflects that.
Way it all turns red to indicate
that the answer is wrong,
and once we get it
right again, it changes.
And it's all based on it's a little bit
of JavaScript state inside of our React
component.
The state is keeping
track of the first number.
It's keeping track of the second number.
It's keeping track of the response, and
it's keeping track of whether or not
I got the answer right or not.
And so certainly there are things
that I can begin to do now.
Maybe I just want to make
some aesthetic changes.
This has nothing to do
with React specifically,
but I might say, all
right, let's go ahead
and take my entire application and text
the line [INAUDIBLE] it's centered,
give it a font family of sans serif.
This is just me making
some UI improvements just
to make it look a little bit nicer,
even though none of the actual content
is changing.
Let me take the problem
and maybe give it
a font size of 72 point font
just to make the problem bigger.
COLTON OGDEN: The background has some
sports equipment, FRESHiAM style.
BRIAN YU: Yeah, something like that.
So now all right, now
I've got centered text,
the problem is a little
bit bigger, maybe
this is a little closer to
what I want the ultimate web
application to be looking like.
But the missing thing,
at least right now,
is I'd like to keep track
of the user's score.
I'd like to keep track of,
all right, how many questions
has the user gotten right.
So how am I going to
go about doing that?
Let me go back here.
And the score, as you
might guess, is also
going to be part of
this component state.
Part of this application
is not only going
to keep track of the response of
what the two current numbers are,
but it's also going to keep track
of what the user's current score is,
for instance.
And so inside of here,
I'm going to add part
of the state that is equal to score, and
score by default is just going to be 0.
Now I'll scroll down here, and
underneath the input field,
let me go ahead and just say score.
And let me fill in the score
into this part of the HTML page,
and I'm going to do that
by saying, this.set.score
to mean, all right, let's display the
score in this part of the HTML page.
COLTON OGDEN: Using Vim
key bindings and VS code.
I would do something like
that, says Bavick Knight.
BRIAN YU: Oh yeah.
I like the combination
of VS code and Vim a lot.
There are a couple of good
Vim extensions in VS code.
If you just go to the
extensions page in VS code,
there are several good Vim
extensions that work pretty well.
I think I'm just using the most
popular one in this case, that
adds a lot of the standard
Vim key binding support
into your VS code editor,
and so that can definitely
be a helpful thing to do.
COLTON OGDEN: Do you or do
you not also do it for Chrome?
BRIAN YU: Do I do it for Chrome.
Oh yeah, I also have a Chrome extension.
It's called Vimium, I
think, that allows me
to use Vim controls in order to scroll
through a website, for instance.
If I go to like the New York Times
website, for instance, I can--
J in Vim means go down
a line, for instance.
I can press J, which takes
me down through the page.
K brings me up, for instance.
And so you can do that as well.
All right, so I've now
defined score, and I've
tried to insert that score into
the main part of this website.
Again, all of this is inside of this
render function, this function that
runs any time that I try to load the
contents of this particular component
such that now if I refresh
the page, we see that I see
2 plus 2, input field, and score is 0.
And all right, this isn't probably
the greatest of user interfaces.
I probably want score to
be on a line of its own.
Anything contained within a div is
going to get basically a horizontal area
of the web page to itself, and so I'm
going to surround score inside of a div
now, such that now I can say.
OK.
Score is 0, and that
looks a little bit nicer.
And of course, there are UI
improvements we can make here,
but for now this is
going to work just fine.
I get a question right.
1 plus 1 equals 2.
And the score stays 0.
So OK, that's not quite what I want.
What I want to do is, when
I get the question right,
I want to update the
state of my component.
I want to update the
score to be whatever
the updated score should
be, in other words, 1 plus
what the score was previously.
So the simple way to do that is down
here, when I get the answer right
and I update the state to
give myself two new numbers,
to clear out the response
field, to say that I didn't
get the response incorrect,
would be to also say,
score equals something in particular.
In this case, this.state.score plus 1
might be a reasonable way to do that.
And this would work.
If I went back here, refresh the page,
1 plus 1, I get the answer right.
I click 2, for instance.
I get it right.
All right.
The score updates.
I get a new problem.
Input field clears out.
The score is now 1.
I type 6, for instance, get
that right, my score is now 2.
If I get the answer wrong, press
Return, clears out, turns red,
score doesn't change because
I'm not updating the score
state when I get the answer wrong.
Now you might imagine
different game mechanics.
Maybe I want the score to decrease if
I get the answer wrong, for instance.
You could do that too.
But for now I'm saying if
you get the answer wrong,
just go ahead and
don't change the score.
There is one minor design issue
with this particular paradigm,
and this gets to be a little bit more
advanced in terms of how React works.
But one interesting
thing is that technically
speaking, when I say
this.state.score plus 1
and set that equal to the new score,
this opens me up to something called,
maybe not in this particular case,
but doing something similar to this
in other React components, especially
as your React applications get
more complicated, this does open
me up to potential race conditions,
where the idea might
be, if I'm evaluating
the value of this.state.score
before the state has totally updated
or while someone else is trying
to update the same state,
or some different part
of the application
is also trying to update the state,
there's a potential for conflict there.
And so there are many
ways to deal with this,
but React actually has a pretty
straightforward way of dealing
with this, and that's to say that right
now, setState is taking as its argument
a JavaScript object, meaning here
is the updates that you should
be making to the JavaScript state.
If I instead wanted to say,
let's try and update the state
but make the new state dependent
upon whatever the previous state was
in a way that doesn't open
myself up to race conditions,
you can instead pass the
this.setState a function,
a function that takes the state
as an argument and returns
whatever I want the new state to be.
And then instead of this.state.score,
I would just say state.score,
where this state refers to
this argument to the function.
And so slightly more complicated.
The reason I'm doing this is just to
be consistent with best React design
paradigms, in particular trying to
avoid the potential for race conditions.
No worries if that was a
little bit complicated.
SetState can also just as easily
take a JavaScript object as well.
COLTON OGDEN: Bavick
Knight was asking, you
have to set score as a class variable,
right, instead of an instance variable.
BRIAN YU: In this
case, this.state itself
is an instance variable
that is going to contain
all of the parts of this
particular component.
And you might imagine
that if we wanted to,
we could create two of these games,
for instance, running in parallel,
where each one had its
own score, for instance.
We could do this right now, actually.
Instead of just div App, if I
copy that and call this div App
2, for example, and then
down here at the bottom,
in addition to rendering
the app inside of App,
I also rendered the app inside of App 2.
So now I only defined the class
once, but I'm rendering it twice
in two different parts of my HTML page.
You might imagine that now,
if I refresh the page--
why didn't that work?
COLTON OGDEN: Because your thing's just
looking for just the App ID, right,
not App 2?
BRIAN YU: Target container
is not a DOM element.
ID App 2.
COLTON OGDEN: Oh, I know.
That is your preselector.
BRIAN YU: Target [INAUDIBLE]
is not a DOM element.
I'm not entirely sure
why that's happening.
But let me try to get
back to you on that one.
For now, we'll just try and
render the application once.
COLTON OGDEN: Part of
the fun of live coding.
BRIAN YU: Yep, indeed.
COLTON OGDEN: But the
point, I guess, that we see,
is you wouldn't necessarily have
just one app or whatever component.
It wouldn't want to be a
static variable necessarily.
It's good to have it
be an instance variable
so you could have multiple
components running together.
BRIAN YU: Yeah, exactly.
And I wonder-- actually, let
me try this one more time.
Let's see if instead of just rendering--
COLTON OGDEN: If it
makes you feel better,
I messed up big time on camera
like three times last stream.
BRIAN YU: No worries.
Let's try this and see if it'll work.
Let's render a div inside of which
we're going to render App twice,
which we should be able to do.
If we refresh that, all right, great.
Now there we go.
Now we've rendered the
application twice inside of this.
And you'll notice that each one of them
is going to function independently.
If I get an answer right here, get
an answer right, get an answer right,
get an answer wrong, I can
have an independent score.
I have independent problems.
I have independent, did I get the answer
right or not, running simultaneously.
Each one is just an instantiation
of this App component,
and I can use that App
component multiple times,
and each one is going to have access
to its own state, for instance.
And so that's what's
going on here, in order
to allow me to basically run
the same thing multiple times.
COLTON OGDEN: Nicely done.
That was fast, too.
Cloud FF06 says, hey from South Africa.
Good to have you, Cloud.
Thanks for joining us today.
And Bavick Knight says, wow.
He's impressed too.
BRIAN YU: Glad we were
able to get that working.
All right.
But we'll go back to
just having one game
because that'll make things a little
bit simpler just for our purposes.
But you can imagine that now you have
this capacity of reusing components
if you wanted to create a multiplayer
game, for instance, where people are
racing to see who can get
to a particular score first,
that would be something you can do.
And that's one of the beauties
of react components, which
is that you design them once.
They self-contain their own
state and their behavior
and how they should
behave, and you can then
reuse those components in other parts of
your application wherever you see fit.
You can reuse them multiple
times if need be, and all of that
goes to show just the
power of what React allows
you to do using these components.
So all right, we're
almost at the state place
where we basically have
a complete application.
Maybe the last thing we'd like to do
is allow the user to win this game.
Right now, this game
could go on forever.
You could just keep answering
questions again and again
and again, and you would never
get to the end of this game.
Your score would just keep
going up and up and up and up.
Maybe we want to say, all right, once
you get to a score of 10, for instance,
we're going to allow
you to win the game.
We'll just say, OK, you've
won the game, game over,
at the point at which
you get a score of 10.
How might we go about doing that?
One thing you might imagine
doing is you might say, OK, well,
we could add a part to the
state to say, all right,
have you won the game or not, and
add that as something the state
is keeping track of.
But we really don't need that.
We can infer whether or not
you've won the game based
on the existing values of the state.
And this is part of the React design
paradigm, that I could add like a 1,
which is set to false, for instance,
and when I get to a score of 10,
update 1 to be true, for instance.
But this is a duplication
of state information,
technically, that all the information
I need to determine whether or not
the user won is inside of the
score or part of the state,
so I don't need 1 to be
able to tell me that too.
And in fact, having both opens
myself up to potential bugs,
like what happens if the
score is 15 but 1 is false.
Those seem to be in direct
contradiction with each other,
and so oftentimes, a good thing to
do is, only keep around the state
that you actually need such that you can
just infer what the rest of the state
should be based on the
state that you have.
And so that's what I'm
going to do here, just
infer whether or not
you've won the game based
on what the current value of score is.
COLTON OGDEN: Gossen says,
hey Colton, let's add some GUI
and turn it into like
a Flappy Bird game.
I don't know if we'll have enough
time for that on stream today,
but in my games course, we do
look at Flappy Bird from scratch,
so I'll toss the link in
the chat here as well.
BRIAN YU: Yeah, definitely
another good course
to take a look at if game development
is something that's interesting to you.
This is just going to be a
very simple text based game,
but a whole lot more opportunities
for game development,
and we have some lectures
on them that Colton's
done to help you with
that if you're interested.
COLTON OGDEN: Awesome.
BRIAN YU: So all right, thus
far throughout the design
of our application, what the
user interface's structure
has looked like has never changed.
The numbers have changed,
the score has changed,
what the user's typed into has changed,
but the structure of it, of OK, number
plus number, input field, score, that
stays the same throughout the entirety
of the gameplay.
When the user wins the game, I
probably want to clear out the problem,
clear out the input
field, clear out the score
and just show some
text that says you won,
for instance, which means that
I can't just always render
this sequence of divs that are
going to display the same thing
every single time.
And so here's what I might do instead.
What I might do is, inside of the Render
function, rather than call this Render,
I'm going to call this function
Render Problem as in this case,
I just want to render a new problem
for the user to try and solve.
And at the end of the game,
once the user's won the game,
there's going to be no need to call
Render Problem anymore because there's
going to be no more problem to display.
The user's won the game, and we can go
ahead and move forward and just display
a screen that says
congratulations, you won.
Now, React doesn't natively
understand what Render Problem is.
React still requires me to have
some function called Render
that's going to return something.
You might imagine that I could do
something like this, where I might say,
if this.state.score is
equal to 10, then let
me return this.renderwin, which is
a function that I've yet to define,
meaning if the score is 10,
once I get to a score of 10,
go ahead and render some page
that says, all right, you've one.
Else, go ahead and return
this.renderproblem.
So what's the logic here?
The logic is, once I've reached a
score of 10 and I've won the game,
we're going to call the
Render Win function,
and that's going to decide
what I render on the screen.
Otherwise, if I haven't
yet reached a score of 10,
then I'm going to return
this.renderproblem, which is going
to be the same thing that I did before.
This whole function is
going to return to me
what it is that is the problem
that the user needs to be solving.
COLTON OGDEN: Will you be doing error
handling, i.e. random character insert?
BRIAN YU: Good question.
We actually handled random character
insert as we talked about, a little bit
ago, you may have
missed it, but the idea
is that if I type like a text
character rather than a number
into the input field, then
we might run into a scenario
where we're calling parseint on
something that isn't an integer.
And as we found out by looking
at the JavaScript console,
when we call something like
parseint on something like Hello
that's not in fact an integer,
what we end up getting
is not a number, a special JavaScript
value that means it's not a number,
and that's actually OK.
We can just compare to see whether
the sum is equal to that not a number
value, in which case it's
not going to be equal,
and so that's going to be an
indication that the number is invalid,
for instance.
COLTON OGDEN: I don't mean to
put you too much on the spot,
but would this code be
on GitHub, by chance?
Can be share it with people?
BRIAN YU: Yeah.
We can find a way to share
this with you afterwards.
COLTON OGDEN: OK.
[INAUDIBLE] a link.
I'll put in the YouTube.
BRIAN YU: Yeah, we can do that.
COLTON OGDEN: On game one, you
should shoot some particles
and play a fanfare sound.
BRIAN YU: Certainly, you could do that.
Probably beyond the scope of what
we're going to be doing here today.
COLTON OGDEN: And [INAUDIBLE]
says, hello, Brian.
Nice to see you on the Livestream.
BRIAN YU: Hello.
Great to have you with us today.
So all right, back to winning the game.
We've defined this
Render Problem function,
but the function we
haven't yet defined is
the Render Win function
for what happens when
the user does in fact win this game.
And so let's go ahead and define that.
Down here, say, Render Win.
And when you win, let's return some div.
We'll call it a div whose ID is winner,
and we're just going to say, you win.
And that's it.
So now let's try playing this game.
We get 1 plus 1.
I get the answer right.
Get the answer right again.
And we'll answer a couple of questions.
Got the same question
twice in a row, which
can happen if you end up generating
random numbers every time.
It's going to happen from time to time.
We could add some extra checking to
make sure you get a distinct question
every single time if you wanted to.
That's certainly something we could do.
3, 13, 14, and all right.
We got 10 questions right, and now
rather than calling Render Problem,
we're instead calling Render Win,
and what we get as a result of that
is a screen that says, you win, and none
of the rest of the content of the page
is there anymore because we're
not calling the Render Problem
function, which is the
function that's ultimately
going to be displaying the problem and
the input field and the score field.
It's just going to display you win.
COLTON OGDEN: Some virtual fanfare.
BRIAN YU: Yeah, virtual fanfare.
You know, we could style
it up a little bit.
We go up here and say, all right,
for the winner, let's go ahead
and change the font size to 72 pixels.
Let's go ahead and change
the color to be green.
And then we could try winning again.
For the sake of time, I'm going to
say when I get three questions right,
we win the game.
So 2, 15, get the third question
right, and all right, you
win shows up in green in big
text, and so that's something
that you can do there as well.
COLTON OGDEN: Nice.
BRIAN YU: All right,
so there we have it.
There is actually a complete
React web application
that just exists inside
of an HTML file now
that allows for maintaining a state
that dynamically updates itself
based upon that state, and so hopefully
that gave you a good sense for React.
We still have some time left,
though, so happy to answer questions
if there are particular questions
about aspects or features of React,
or if we want to make
particular extensions
to this particular application,
certainly something we
could do there as well.
COLTON OGDEN: Yeah, that
was an excellent talk.
Thank you so much for
coming on the stream today.
BRIAN YU: Yeah, of course.
COLTON OGDEN: But yeah, we'll
stick around for a few minutes.
So if you have any questions,
let us know, and yeah.
That was React, flashcards.
Feels nice building something tangible
that people can at the end of the day
look at and experiment
with, because we're
talking in sort of abstract
terms, a lot of frameworks,
but it's nice to actually
see it be sort of put
to the grindstone for
an actual use case.
BRIAN YU: Definitely.
One last thing I'll show, actually,
since we have a little bit of time.
One nice thing about React
that we haven't even seen yet
so far is nesting components
within each other, which
I mentioned at the very
beginning, but we didn't actually
get a chance to see them.
So maybe this You Won component,
that right now is actually
a pretty simple one that just
says you won, for example, we
might want to separate that
out into a different component,
for instance, just like a
winner component that gets
displayed anytime you win something.
You might imagine that if
this application were extended
to have a whole bunch
of different games that
are part of this, that you might
have the winner screen appear on all
those different games
once you win it, and we
might want to factor that out into
a different component, for example.
And so we could do that pretty easily,
by instead of just defining a class
called App, let's also
define a class called Winner
that also extends react.component.
And this defines a
render function that's
just going to return a div whose
ID is winner, that says you win.
Same as before, but we've just separate
out into this winner component.
And down here, in Render Win,
rather than returning this div,
I can just say Return Winner,
return that Winner component,
and let me set the game
winning score to be three just
to make this a little easier again.
And assuming we did everything
right here, if I refresh the game,
you get some questions right,
get the last question right,
we still get the same
you win that shows up.
But this time rather than just being
part of the same app component,
it's part of a separate component,
and so this Winner component
might be something that other
games could use as well.
Now you might imagine that maybe we want
this Winter component to be customized,
for instance, that doesn't
just always say you win,
but says you win, like,
the addition game,
for instance, where we have the name
of the game as part of the winner
component.
Now of course, the name of the game is
going to vary depending upon the game,
so different games might try to render
the Winner component in different ways.
And so what am I do in this case is
to say, you win, and what I want to do
is not just render a Winner
component, but pass some information
into the Winner component,
pass information
the same way you might pass arguments
to a function, for instance.
We're going to pass
what are called props
to this component where I'm going
to say maybe the name of the game.
Const name is the addition game.
And I'm going to say, all right,
winner, let's pass in a variable called
name that is equal to
this JavaScript value,
again using the curly braces to mean
insert a JavaScript variable here,
that is called Name.
So this is something
we haven't seen before.
This is an example of a React prop,
a property of the Winner component
that I want to pass into the Winner
component such that it can use it.
And these props, unlike the state,
which can change and can update,
the props are never going to change.
You pass in the name into
the Winner component,
and the Winner component is never
going to change its own props.
COLTON OGDEN: It's like in an image
tag, having like, source equals
[INTERPOSING VOICES]
BRIAN YU: Yeah.
COLTON OGDEN: Actual app.
BRIAN YU: Yeah, exactly.
It's very similar to an
HTML attribute, the way
you would add a source for an image
tag or an href for a link tag,
for instance.
That's the same idea.
And so now here in Winner,
rather than just saying
you win, I can say you win
this.props.name, meaning take the props
and extract the name
from them and display it
there such that now if I play the game,
oh I've got 1 plus 1 for a second time,
1 plus 6, get that right, you
win the addition game, right.
We've been able to shrink that down
so you can see it a little bit better.
COLTON OGDEN: I have the chat
in the way a little bit there.
BRIAN YU: No worries.
And so that's allowed us ultimately to
customize this Winner component even
when using it from an outside component
by passing in some prop, the addition
game, into the Winner component
such that it can display and render
correctly.
You might imagine that other games
that are also using the same Winner
component could use the same component
but pass different props into it as
well.
COLTON OGDEN: Makes everything
super nice and modular.
M Kloppenberg says, thanks, Brian.
Clear as always.
Enjoyed your CS50's wen
explanations as well.
BRIAN YU: Great.
Glad to hear it.
Glad you enjoyed it.
COLTON OGDEN: Can you write an app
for the typing test, says [INAUDIBLE]..
Probably not today, but
maybe in the future.
That would be a cool idea, actually.
BRIAN YU: Not today,
but certainly something
you could do with the knowledge
that you have with React right now.
It would really be probably some state.
Maybe that state is going
to contain information
about what it is the
user's expected to type,
and state about what the
user has actually typed.
It might contain state about what time
they started typing, for instance,
and then based on the current
time, the time they started typing,
and the number of
characters they've typed,
you could probably estimate a
rate at which they were typing,
and maybe you have some algorithm
for factoring in mistakes they make
or errors they make there as well.
So definitely something that you could
do using the same general paradigm.
COLTON OGDEN: France P asks, any
thoughts on the new React feature
hooks?
BRIAN YU: New React feature hooks.
Actually not too familiar with those
feature hooks, but happy to chat
more about that later afterwards.
If you want to shoot me
an email or some instance,
I'm happy to chat about that too.
COLTON OGDEN: Do you want to maybe
read off Cloud's question after that?
BRIAN YU: When you
added the second app in,
could you create a
multiplayer kind of interface
that compares scores at the
end of both player's completion
and displays the overall winner?
Would increasing difficulty
be as easier as easy
as increasing the
multiplied random number
each time you get a correct answer?
Yeah, certainly.
So two separate questions there,
one about the multiplayer game.
So for those who have
joined a little bit late,
one thing we did at
the beginning of this
was to say, all right,
what if we, instead
of just rendering the application once,
tried rendering the application twice.
So I have the application twice
here inside of the same div,
and then I rendered the game
here such that I now have
two parallel games that are going on.
Certainly you could imagine that we
had an interface that compare scores
at the end of it and tells you
who was the overall winner.
But in order to do
that, you probably would
need to have some other component,
some wrapping component that
wraps the two games, and that contains
its own state of keeping track of like,
who is winning the game, that handles
events for when an application wins
a game, for instance.
So definitely something you could do.
It would just require probably
an additional component
to keep track of managing
all those different games.
COLTON OGDEN: Like a game manager,
and then those two are app manager,
and then have those two apps.
BRIAN YU: Yeah, yeah.
Exactly.
Would increasing the difficulty
be as easy as increasing
the multiplied random number each
time you get a correct answer?
Yes, exactly, and in fact,
we could do that right now
without a whole lot of difficulty.
Rather than just adding numbers from--
let's try and find it.
This will get us numbers from 1 to 10.
If we want to make the game
more difficult, actually,
why don't we try taking
a number from 1 to 10
and adding state.score
to it, for instance?
So this will update the random number,
adding whatever the current score is,
such that as my score
gets higher, the numbers
that are inputted get more
difficult. And let's go ahead
and change the winning threshold
to 10 just so we can get some more
opportunity to try questions.
But now all right, 2, 11,
yep, 15, 17, and all right.
So now, 12 plus 12,
this is not a problem
that we would have gotten before if we
were just going from a 1 to 10 scale,
but because we're now increasing
the values of the numbers
that we're typing in,
every time we do it,
we're going to start seeing
higher and higher numbers.
And if we do it a couple
more times, like 15 plus 14,
these are the types of numbers that we
weren't getting in the original game.
But by increasing the
number, you could definitely
make the game a little
bit more exciting.
COLTON OGDEN: Thanks, Brian.
You explained very well everything.
You did a good job, awesome job.
Boston Mass says, wait, you're in Mass?
So yeah, we're in
Cambridge, Massachusetts,
where Harvard University is located,
shooting here live from campus,
actually.
Every time there is a long message,
Colton makes the other person read it.
That's actually true.
That's a good point.
I thought that was Zac Efron.
Brian, could you make another session
showing the multiplayer interface?
BRIAN YU: We haven't scheduled
the remainder of sessions yet,
but certainly I would encourage you to
try making the multiplayer interface
if that's something
that's interesting to you.
You can do it using much of the
same technologies and features
that we talked about today, and this
idea of just composing components.
In the same way that we put a Winner
component inside of our app component,
you might have a game
manager component inside
of which are two apps, for instance,
and you could give that a try certainly.
That's Something to work on.
COLTON OGDEN: Why don't
you go ahead and read
the long message towards the bottom?
BRIAN YU: Would adding a
restart button essentially just
be adding a button that instantiates
a fresh copy of the React component
on click?
You could do that.
You could instantiate a fresh
component of the react component,
though what might be easier would
just be resetting the state back
to the original state.
So in fact, let's try that, why not.
It won't be too difficult.
So after the end of the
score, let's add a button,
and that button is going to be reset.
So now we've refreshed the game.
Here is the reset button.
I got some questions
right, but of course,
clicking the reset button
right now does nothing.
So let me add something to this button.
On click, let's call a
function called this.resetgame.
Now of course, I haven't defined Reset
Game yet, so let's define it now.
Let me go down here to the bottom.
Let's do resetgame is going to be
a function that takes in the event,
although actually, I don't think
we're going to need the event.
We're going to set the state.
And all right, what things
do we need to reset?
Well, Num1, let's set it back
to 1, just for the beginning.
Num2, we'll set that back to 1.
The response we'll set
back to the empty string.
Whether or not you've got the answer
incorrect, we'll set that back to false
so it goes back.
The score, we'll set back to zero.
This is the original
state of the application,
and when we reset the game, we're
just going to reset the state back
to the original state, and maybe
you can imagine factoring this out
to avoid duplication.
For now, this will suffice
for our purposes, such
that now, I'm playing the game.
I get some questions right.
Whoops, that was wrong.
16 I type in.
I get a wrong answer, for instance.
All right, my score is three.
I'm not too sure about this question.
The answer is wrong, so the text is red.
But I click the Reset button, and all
right, the game resets back to normal.
The state went back to normal.
Num1 and Num2 go back.
The answer's blank again.
The score goes back to 0.
And so you can generate that
effect of resetting something
just by taking the state and
setting it back to normal.
COLTON OGDEN: Nice.
It's like an encore.
Cool, all right.
Well, it's 3:58.
We'll stick around for a couple more
questions, but tune in on Friday.
On Friday, we're actually going to be
doing some Unity programming in C#,
so a completely different
venture than today.
Oh, Cloud also follows up with his
other question that I made you read.
It says, thank you for answering.
I'm in second year of
software engineering.
Busy with Swift at the moment.
First time encountering your live
feed, and really awesome, so thanks.
Or we can define
original state function,
and just use that function to call.
More modular, less dry.
BRIAN YU: Yeah, exactly.
So I mentioned before that I was
doing a bit of duplication of code
here, where in the
reset game, the state I
was setting it to was
equivalent to the state
that I was originally
setting the stop state to.
So you could imagine either putting it
inside of some sort of class variable
that everything has access
to, or by using a function,
for instance, that you could try to
avoid that need for that redundancy,
for instance.
COLTON OGDEN: Is your computer
equipped to do GitHub on this account?
Would you be able to fire up a
link for it so it's in the video,
or do you want to wait to do that later?
BRIAN YU: Let's go
ahead and do that later.
COLTON OGDEN: OK, sure thing.
Yeah, because Bavick Just said, you're
going to put this on GitHub, right.
Please share the link.
We'll share the link, so it's
going to go up on YouTube,
and it'll be in the description.
We'll post the GitHub link
in the description there.
We're going to stick around
for just a couple more minutes,
but we hit an hour and a half, which
that's the David time, as well.
BRIAN YU: Is it?
An hour and a half?
All right.
COLTON OGDEN: It's a
good amount of time.
But yeah, that's a nice example.
It kind of introduces all the
core concepts very nicely.
BRIAN YU: Yeah.
Thanks, everyone, for listening.
Hope you enjoyed.
Hope you learned a little
bit more about React
and how it can be useful, as opposed
to just using plain old JavaScript,
which you could design an application
like this just using JavaScript.
Certainly react is not necessary
to do something like it.
But especially as web
applications get more complicated
and web interfaces get more involved
in the front end, and what's going on,
and there's a lot of things happening
and a lot of things changing
inside of the application, React
can just be very, very powerful
for trying to minimize the
amount of code you have to write
and maximizing the expressiveness
of the work that you're doing.
Again, I'm Brian.
COLTON OGDEN: Colton Ogden.
So Brian, you head
teaching fellow for CS50.
What class are you?
BRIAN YU: I am currently
a senior at the college.
COLTON OGDEN: So the 19?
BRIAN YU: Class of 2019.
COLTON OGDEN: Class of 2019.
And I am Colton Ogden, technologist
here at Harvard University.
And we do this stream so far pretty
consistently four times a week-ish.
So again, we'll be doing
another stream on Friday.
Students or teachers?
Well, you're both.
Brian taught the CS50 web class.
I'll put the link in the chat
one more time so they're here.
So Brian taught cs50.edx.org/web,
which was not a React course,
but like you said earlier, much more
of a back end oriented, Flask, Django,
that sort of thing, cyber security and
excellent GitHub first lecture too,
if you want to review
some GitHub fundamentals.
And then I am not a student here,
but I am a full time technologist
and also do a little bit of
teaching and other stuff.
And I taught a games course.
So you can go to both those links.
Those are both of our courses
from this year on edX.
So awesome.
[INAUDIBLE] says this was great.
Thank you both.
Have a great day.
Thanks so much, [INAUDIBLE].
Thanks for coming by again.
And thanks so much, everybody else.
We'll go to the wide
shot here where we still
see the chat on the left hand side.
So this was Brian Yu
with an intro to React.
Stay tuned for Friday, but
this is CS50 on Twitch.
Anything you'd like to follow up with?
BRIAN YU: Yeah, thanks so much.
Enjoy the rest of your day.
COLTON OGDEN: Awesome.
Thanks so much.
