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