Placeholder Image

字幕列表 影片播放

  • COLTON OGDEN: All right.

  • Hello, world.

  • This is CS50 on Twitch.

  • I'm Colton Ogden.

  • I'm joined today by CS50's Brian Yu.

  • Brian, what will you be talking to us today about?

  • BRIAN YU: Hey, everyone.

  • Today we're going to be talking about React, which is a web framework that's

  • designed to help make it easier to develop dynamic web applications that

  • have interactive user interfaces.

  • So we'll be taking a look at how to get started with that,

  • some of the basic features of it.

  • We'll only scratch the surface because there's a lot to React,

  • but hopefully you'll learn enough over the course of the next two hours

  • or so to get a good sense for how to use React to build

  • a web application of your very own.

  • COLTON OGDEN: And Brian is CS50's head teaching fellow currently,

  • and also taught a course through the Extension School, the web course.

  • Let me just plug that really fast here. cs50.nx.org/web,

  • if anybody's interested.

  • What were some of the topics that you taught in that web class?

  • BRIAN YU: Yeah, the web development course was a course we ran last spring.

  • It was about web application development using Python and JavaScript,

  • so we talked about continuing where CS50 leaves off,

  • talking about the design and implementation of web applications

  • using Flask.

  • We moved to a more advanced Python based web framework

  • called Django that has a bunch of additional features as well.

  • And throughout the course, we were talking

  • about issues of database design and security and scalability,

  • and ultimately how to design and deploy web applications on the internet.

  • So all of those lectures that are freely available online, definitely

  • feel free to check those out if that's something that's interesting to you.

  • COLTON OGDEN: And so would you say that's more of a back end course,

  • and what we're doing today is a little bit more on the front end?

  • BRIAN YU: Yeah, I'd say that there was a lot of back end

  • work over the course of that class where we were teaching things

  • about how to design API, for instance, how to design ORMs for interacting

  • with databases in particular, although we did touch on some JavaScript

  • on the front end.

  • Today is going to be entirely front end.

  • React is really a framework designed for front end web development,

  • and you can connect it with just about any back end

  • that you use, not necessarily written in JavaScript.

  • You could connect it with a Flask or Django app,

  • for instance, or some other web server.

  • COLTON OGDEN: OK.

  • Super excited.

  • I know React is one of the big front end frameworks.

  • Is it the biggest one?

  • BRIAN YU: As of right now, it's the biggest.

  • So these web frameworks sort of come and go, and they sometimes get more popular

  • and lose popularity.

  • Right now, React is number one in terms of popularity.

  • Number two is Angular, which is developed by Google.

  • The Angular 2 is a relatively recent addition to the mix,

  • and then there are other frameworks as well,

  • such as View that are also growing in popularity as well.

  • COLTON OGDEN: Awesome.

  • So we've got a couple of comments there in the chat.

  • We've got some regulars here.

  • So Bavick Knight and [INAUDIBLE] are regular folks who join us all the time.

  • Say, I'm on time today, says Bavick.

  • [INAUDIBLE] saying hello, how are you.

  • M Kloppenberg says, hello, everybody.

  • Good to see you, M Kloppenberg, And oh, it

  • looks like Bavick says he's enrolled in the web course.

  • I want to learn more about it, about Django, he says.

  • BRIAN YU: All right.

  • Great.

  • Glad to hear you enrolled.

  • Yeah, Django comes a little more than halfway through the course.

  • It gives us an opportunity to start to talk about testing our code

  • in order to make sure that our routes work properly,

  • and it gives us an opportunity to talk about security and some other issues.

  • So definitely look forward to that.

  • COLTON OGDEN: Awesome.

  • Cool.

  • Cool.

  • All right, well, do you want me to bring your computer up here

  • and we can start taking a look?

  • BRIAN YU: Yeah, sure.

  • Let's do it.

  • So let's start by working on a very simple web front end using Django,

  • and what I have here is just a basic HTML

  • file, the same way that you would design any other HTML

  • file if I were building a web page.

  • But what you'll notice right here just to start us off,

  • I've added three scripts that we're going

  • to use in order to allow us to add some React code into this HTML file.

  • So the first one up here on line four, I am importing the React library itself,

  • the development version of the React library.

  • On the next line, I'm importing a related library called ReactDOM.

  • This is going to be a library that's going

  • to give us the ability to take some React code

  • and actually render it inside of the DOM.

  • And if you're unfamiliar, the DOM or the document object model

  • describes the structure of the web page, because we're going to say,

  • we're going to add some HTML element to this web page eventually,

  • and we're going to say, this HTML element

  • is one where we want to play some React elements inside of it.

  • And so we'll place some of what are actually

  • called React components, inside of our HTML page,

  • and ReactDOM is going to help us do that.

  • And React is interesting in the sense that while you can write it

  • in pure JavaScript, the convention nowadays

  • is to use something called JSX.

  • It's not just JavaScript, but JavaScript X,

  • where the convention is to mix our JavaScript and our HTML elements

  • together.

  • Where in JavaScript natively, things like integers and strings and functions

  • can all be considered values, in JSX, we can consider HTML elements to be values

  • as well, and we can use regular HTML like syntax in order

  • to define an HTML element that we could save to a variable, for instance,

  • and put in a list of other HTML elements,

  • which gives us a lot of expressive power, which

  • we'll see in just a moment.

  • And so this last script right here, Babel,

  • that's going to take care of translating the JSX

  • code into regular JavaScript which our web

  • browser is going to be able to understand such that we can render it.

  • So let's go ahead and get started by building something very, very simple.

  • So inside of the body of my web application,

  • the first thing I'm going to do is create

  • an area inside of the body of my application

  • where this React application is going to live.

  • And generally speaking, this is going to be a div element.

  • A div just defines some block of the web page

  • where some particular HTML content is going to go,

  • and this div is going to have an ID of App,

  • because app is just an arbitrary name that we're saying,

  • but we're going to identify this div by the ID.

  • The ID is App, such that later in the JavaScript code

  • that we're about to write, we're going to say

  • take some React component or some piece of React code

  • and insert it into the div called app.

  • So we're giving it a name such that later, we can begin to reference it.

  • COLTON OGDEN: It looks like Shana G says hello with the Bob Ross icon.

  • I think it's become a trope, the streams that

  • make some people feel like we're watching a CS version of Bob Ross.

  • Bavick Knight says how is React different from Ajax and jQuery?

  • BRIAN YU: Good question.

  • So Ajax is sort of separate.

  • The idea of Ajax is just the mechanism of a client asking

  • a server for additional information without needing to reload the page,

  • for instance.

  • So for instance, if you're in a chat application on Facebook Messenger,

  • or GroupMe or WhatsApp or whatever chat application you happen to be using,

  • and someone sends you a message, you don't

  • need to refresh that page in order to get the next message,

  • and that's due to some technology.

  • Web sockets are a popular way to do that,

  • but you could do this using something like Ajax,

  • where the idea is that you are asking the web

  • server for additional information, and that new information gets

  • loaded on the page without you necessarily having to do anything.

  • So for instance, this is the way Twitter, for instance,

  • might go about loading new tweets.

  • If new tweets come in while you're still on a page,

  • if you were watching the New York Times website last night

  • and you lived in the United States, for the US midterm elections

  • you saw a similar thing, where you didn't have to refresh the New York

  • Times page, but new content about the latest election results were coming in.

  • That can all be done via Ajax, for instance.

  • And jQuery, meanwhile, is an older JavaScript library,

  • and that JavaScript library is designed to make some things easier,

  • in particular trying to select elements and trying

  • to modify elements in particular ways.

  • And so you can certainly use pure JavaScript or jQuery

  • to do a lot of the things that React can do.

  • React is just designed to allow for what we

  • had called stateful components, components that can update

  • based on some sort of internal state.

  • And we'll see an example of that shortly.

  • COLTON OGDEN: Would you maybe use React and Ajax together in an application?

  • BRIAN YU: Yeah, certainly.

  • If you had a React front end and some sort of back end server,

  • you might, inside of your React code, make Ajax requests,

  • make calls to a web server in order to ask for additional information

  • that you would then render inside of your web application.

  • We won't see that today, but definitely something

  • that you could do using React.

  • COLTON OGDEN: Nuanda 3333, who's [INAUDIBLE] says, finally

  • JavaScript with heart.

  • So people have been very excited for that.

  • Very thorough explanation.

  • Wow.

  • Best says, Bavick Knight.

  • Awesome.

  • BRIAN YU: All right.

  • So we have this div right now that just says App,

  • but right now this div is empty.

  • So this slash then greater than symbol just

  • means there's nothing inside of this div right now.

  • And in fact, if I were to go ahead and open index.html inside

  • of my web browser chrome, what you'll notice is right now, it's blank.

  • There's nothing there.

  • So let's go ahead and put something inside of this web page

  • such that we can do something interesting with it.

  • And to do this, I'm going to use some JavaScript code.

  • So I'm going to put this JavaScript inside of a script tag,

  • but because I'm going to be writing JavaScript X,

  • JSX code instead of pure JavaScript, what I need to do

  • is transpile that code from JSX into regular JavaScript

  • that my web browser is going to be able to understand.

  • And so to do that, I'm going to say this script's type

  • is going to be text/babel, and what that's

  • going to say is that Babel, which is the technology that's

  • going to do this transpilation for us, is going to take this code,

  • and before it actually renders the page, the first thing it's going to do

  • is transpile or translate this code into regular JavaScript such that Chrome,

  • my web browser, which doesn't understand JSX

  • but does understand pure JavaScript, is going to be able to understand it.

  • So what's the code that I'm going to write?

  • Well, in general, we're going to create React components.

  • So any piece of your website you can generally consider to be a component,

  • and one way that React likes to think about user interfaces

  • is by taking a user interface and dividing it

  • up into the different components that make it up.

  • So for instance, an application might have a menu bar that has a component.

  • It might have a form that has a particular component.

  • A visualization of data in a particular way might be a component.

  • And components can even be nested within each other.

  • You can have a component that has components inside of it, for instance.

  • COLTON OGDEN: Like a form can have a bunch of subcomponents, like text

  • fields and dropdowns and stuff like that.

  • BRIAN YU: Yeah, certainly.

  • That definitely would be possible.

  • COLTON OGDEN: Gossen says, is Bootstrap--

  • I'm assuming he means Bootstrap the framework-- different from React?

  • BRIAN YU: Good question.

  • So Bootstrap is a CSS and JavaScript library

  • that's designed to help style our websites a little

  • more easily and add some basic interactive features, things like form

  • validation that Bootstrap allows for.

  • It is different, but you can use them together.

  • So React is going to be what's taking care

  • of the logic of like what ultimately gets displayed on the page based

  • on the state of the website, as we'll soon see,

  • and you could add Bootstrap to this application in order to say,

  • I want to style this web page in a particular way,

  • and Bootstrap offers some great CSS code that just makes a website look

  • a whole lot more modern and look a whole lot better

  • without you having go through the effort of writing

  • a lot of that same CSS for yourself.

  • And so you could definitely use these in conjunction.

  • COLTON OGDEN: Awesome.

  • BRIAN YU: All right, so we're going to create a React component,

  • and to do that, we're going to use the latest version of JavaScript that's

  • called ES6, and it allows us to define classes.

  • So this is something you may be familiar with if you're

  • familiar with other object oriented programming

  • languages, like Java for instance.

  • But the idea of a class is, we're going to define what this component is,

  • and then we can instantiate that class, or say, let's create a new component

  • and put it somewhere inside of my web application.

  • And so I'm going to define a basic class, which

  • is going to be called Hello, which is just going to be a React component that

  • is going to say hello on my page.

  • And I'm going to say this class Hello is going to extend react.component.

  • So the idea here, if you're familiar with object oriented programming,

  • is that the Hello class is going to inherit from the React component class.

  • But if you're not familiar with object oriented programming, totally OK.

  • The basic takeaway here is that Hello is an example of such a component.

  • All right, so we have this React component,

  • and what we need to tell this component is, what should this component do when

  • we tried to render it to the screen, when we try to render it inside

  • of the DOM, render it on this web page.

  • And to do that, we're going to give it a method called Render,

  • and this Render method or function is going

  • to return what it is that gets displayed on the page when

  • I try to render this component.

  • And so let me return something.

  • And what I'm going to return is a div that just says hello, for instance.

  • And so this syntax of div followed by Hello and then /div,

  • this is something you might see in just regular HTML, for instance.

  • This is just an HTML element inside of which

  • is, Hello, the text that I want to display inside of this div,

  • and my render function is just saying, Hello is the thing

  • that I want to return when someone tries to render

  • this component onto the screen.

  • COLTON OGDEN: So to actually get to render, or return like sort of raw HTML

  • within our JavaScript, is something we normally definitely don't get to do.

  • BRIAN YU: Exactly.

  • We can just expressively put the HTML that we

  • want to show inside the page right inside of that Render function,

  • this is an example of that JSX syntax, that mixing of HTML elements along

  • with our JavaScript syntax.

  • COLTON OGDEN: Awesome.

  • BRIAN YU: So we've defined this class called Hello,

  • but we haven't yet rendered the Hello element, this component, inside

  • of my HTML page just yet.

  • So that's the last step.

  • So down underneath the class definition, I'm going to say ReactDOM.render,

  • meaning I want to render some React component,

  • and the component I want to render is Hello.

  • And we're going to treat Hello almost as though it's

  • an HTML tag, the same way that div is a tag or body is a tag,

  • and I'm just going to say, let's render this Hello React component.

  • And where do I want to render it?

  • Well, I want to render it back up here where I said, all right, we

  • have this div whose idea is App.

  • That's where I want to render this component

  • inside of the body of my page.

  • So I'm going to say let's render this Hello component

  • inside of that part of the page.

  • And if you're familiar with JavaScript, one thing we can use

  • is something called document.queryselector,

  • which is a built in JavaScript function that's

  • going to allow me to select for a particular part of the page.

  • And if I say documen.queryselector*App, that's going to mean find the thing

  • whose ID is app and render the Hello component there.

  • So that's the basic idea.

  • We defined a class called |

  • that has a render function that basically

  • says what should the Hello component do when

  • I tried to render it to the screen.

  • And then underneath that, after we finished defining the class,

  • we use ReactDOM.render to say, let's take this Hello component

  • and actually render it.

  • And where are we going to render it?

  • We're going to render it inside of this div whose ID is app.

  • So you could imagine if you add a more complex page where you add other HTML

  • elements involved, you could just insert some React code in one particular part

  • of your web page, for instance.

  • COLTON OGDEN: It's almost like it lets us extend the very nature of HTML.

  • BRIAN YU: Yeah, exactly.

  • COLTON OGDEN: Bavick Knight says tags are ended like image tag of HTML for--

  • I'm guessing he's referring to your Hello tag.

  • BRIAN YU: Yeah, so the idea is that this Hello tag, in some HTML tags like div,

  • for instance, we have both an open tag like angle bracket,

  • div, end angle bracket, and then an ending tag, slash div, to mean,

  • all right, this is the end of the div with the content of the div in between.

  • With some tags like the image tag, as you point out,

  • or like the Hello tag in this particular case, we don't need to do that,

  • because it's not that there's any textual or other information that we

  • need in between the start and end tag.

  • All of the information that this Hello component needs in order

  • to render itself is already inside of this Hello class.

  • COLTON OGDEN: I'm guessing there are tags

  • that we could define they do allow us to sort of put other tags nested

  • within other React tags.

  • BRIAN YU: Generally, not too conventional.

  • In fact, what we would likely do is add some

  • of what we would call props to this react component

  • where we could pass additional information,

  • but we would pass them in the way we would

  • pass HTML attributes, for instance.

  • So we would say like, Hello, some property is equal to some value,

  • for instance, which you could do.

  • But in this case, for a relatively simple component,

  • we're ultimately not going to need to do that.

  • COLTON OGDEN: Got you.

  • It looks like Elias says hello.

  • Elias is a regular.

  • Good to see you, Elias.

  • Div tag beneath the body as well, ended on the line.

  • BRIAN YU: Yeah, exactly.

  • So this div right now is empty, and so we didn't need a separate closing

  • tag because there was really nothing inside of that so assuming

  • I did everything right, if I now go back to my web page

  • and refresh the page, we see that now there's Hello rendered on this web

  • page, even though I didn't actually write Hello

  • into the div inside the body itself.

  • All I said was, if we go back to this code,

  • to render this Hello component inside of this div,

  • and the whole component knows that it should just render

  • a div inside of which says, hello.

  • COLTON OGDEN: And that will be reflected.

  • If you looked at the page source, I'm guessing

  • it would just say div, hello world, end div,

  • just like we literally wrote in that component.

  • BRIAN YU: The page source itself is going to contain the JavaScript.

  • So if we look at the page source, for instance--

  • let me shrink this down a little bit--

  • we're going to see the same JavaScript that we originally wrote.

  • COLTON OGDEN: Oh, I see OK.

  • BRIAN YU: But if you take a look, most web browsers nowadays

  • support the idea of like, OK, let's explore the HTML elements that have

  • actually been rendered to the page.

  • So if I control-click and click on Inspect,

  • for instance, I could go to the elements, open up the body,

  • and inside of the div now you can see that we

  • do, in fact, have just a div that says, hello, right there.

  • And so that's the result of what's been rendered inside

  • of that particular application.

  • And you can see that right there.

  • COLTON OGDEN: OK, makes sense.

  • We have an ID equals App as well.

  • BRIAN YU: Yeah, there it is.

  • So that's how we knew where to put that particular div into this web

  • application for now.

  • And so that was our first React component,

  • a React component that allowed us to add some interesting information

  • into this page.

  • What questions do you have about that so far?

  • COLTON OGDEN: There will be like probably a 10 or 15 second delay

  • as well, so if you want to continue, I'll monitor the chat for you as well.

  • BRIAN YU: All right, sounds good.

  • So given that very basics, let's go ahead and try and build something

  • a little bit interesting.

  • And what I thought we'd do today is build

  • a game that uses React as a way of exploring how to manage state,

  • about how to update the HTML of our web page dynamically.

  • And so that's what we're going to try and do.

  • We're going to build a game that is akin to like a flash card type game.

  • I remember my younger brother, for instance,

  • when I was trying to teach him math for the first time,

  • and I would show him flashcards.

  • I've got 1 plus 1.

  • What does that mean?

  • OK, he would say 2.

  • Show him another flash card, 2 plus 3.

  • What is that?

  • And so we're going to build this like addition flash card game.

  • We're going to see what's something plus something up on the screen.

  • There'll be an input field where you can type in an answer.

  • If you get it right, you move on to the next question.

  • If not, you have to try again.

  • And maybe we'll keep score too, eventually,

  • just to keep track of that information.

  • And we're going to do all of that using the power of React.

  • So that's ultimately where we're going to be headed.

  • And so let's try this out.

  • Instead of a class called Hello, let's go out and call this class

  • App, because it's going to be our application,

  • but it could be called anything.

  • And instead of rendering a component called Hello,

  • we're going to render a component called App.

  • And inside of this render function, let's go ahead and render,

  • and I'm going to put this in parentheses just because I'm

  • going to probably take this on in multiple lines

  • just for clarity's sake, though technically you

  • could put it onto one line.

  • It's often conventional if you've got a lot of HTML just to space things

  • out, the same way you would space out HTML even

  • if you weren't using react to do it.

  • And so instead of saying Hello inside of my code,

  • I'm going to instead try to find a question,

  • like an addition question, something plus something else.

  • And so let me create a div where that question is going to go.

  • And for now, I can just say something like 1 plus 1.

  • I'm going to give this div an ID.

  • I'm going to call it Problem for now, just because later I

  • want to do some styling or reference this particular div

  • at some point in time.

  • But right now, it's just going to be a div whose ID is problem,

  • and right now it's just going to say, 1 plus 1, for instance.

  • If I go back to the web page and refresh that, instead of hello,

  • I now see 1 plus 1.

  • So here's the interesting thing.

  • It's not actually going to be all that easy now inside of this 1 plus 1

  • if I ever want to update the problem, if I

  • want to update it to be 2 plus 2, 3 plus 5, for instance,

  • because I'm going to need to find this div

  • and update the contents of this text to be whatever it is

  • that I want the numbers to actually be.

  • And so one of the philosophies of React is that everything belongs in state,

  • or our components have this idea of state,

  • where for any given component, anything that determines any information that it

  • wants to store that could potentially change,

  • you can put in something called the state of the component,

  • and then your HTML inside of the render function

  • can reference that state in order to decide what to display.

  • So what I want to do here is not say this is 1 plus 1,

  • but I want to store these numbers in some kind of state

  • inside of my component such that later on when I render it,

  • I can just say rather than 1 plus 1, let's

  • draw this information from the state of my component.

  • That way, if ever update the state, my web application

  • will also update as well.

  • So for now, it's going to seem like we're

  • doing more work than we need to because we're going to add extra code just

  • to get the same 1 plus 1.

  • But we'll see down the road when we want to change the problem, for instance,

  • or when we want to verify that the user got the answer right, that having

  • this these numbers stored inside of the application state

  • is actually going to be very, very helpful.

  • COLTON OGDEN: It's like declaring variables for our application.

  • BRIAN YU: Yeah, exactly.

  • It's using variables for these numbers rather than just writing the number 1

  • hardcoded into the HTML of the page itself.

  • So to do that, what I'm going to do is inside of a JavaScript class,

  • I can define what's called a constructor.

  • And the constructor is what's going to run when I first

  • create an app, when I first try and create an app

  • and put it into my web application.

  • It's taking this argument called props.

  • These are just additional properties that

  • can be used to modify what it is that this component looks like.

  • We're not going to use these props too much for the sake of right now,

  • but certainly they're a very powerful feature of React,

  • and are especially helpful when you're nesting components within themselves.

  • But the first thing we're going to do is, just

  • because this is a class, it's extending from react.component,

  • I technically need to say, super props, meaning

  • let's let the superclass, the component itself, initialize itself as well,

  • call it its own constructor class.

  • But the interesting stuff that I want to do

  • is set the state, this.state of this particular reactor component.

  • And this.state is going to be a JavaScript object, so a bunch of keys

  • and values, that are going to define what

  • it is that's contained within the state of my react application.

  • So what are the things that are right now

  • in the state of my react application?

  • Well, in the state of this game of showing numbers and typing in results,

  • at minimum I need two pieces of state, one to represent each of the numbers

  • that I want to display on my web application.

  • So I'm going to call those Num1 and I'm going to call it Num2.

  • And by default, each one of them is just going

  • to be 1, such that the first thing that gets displayed on the page

  • is just going to be 1 plus 1.

  • Num1 is going to be the state of the first number in the pair of what's

  • being added.

  • Num2 is going to be the second one.

  • All right, so we've defined the state of the application

  • there in the constructor, and now what I need

  • to do inside of the render function, rather than just say 1 plus 1,

  • I instead want to draw from Num1 and Num2

  • inside of my state to decide what it is that my application is

  • going to look like.

  • So instead of this 1, I'm going to insert a JavaScript value here.

  • And to do that in React, we're going to use the curly brace syntax to mean,

  • insert some variable here.

  • And the variable that I want to insert is this.state.

  • And which part of the state is the first number?

  • Well, it's just called Num1.

  • That's what I defined up on line 17.

  • So I have this.state on Num1, which is going to take Num1 from the state

  • and just insert it right there in the HTML code for my web application.

  • COLTON OGDEN: It's almost like using a templating language.

  • BRIAN YU: Yeah, it's very similar to a templating language

  • if you've used things like Jinja, for instance, along with Flask or Liquid,

  • for instance.

  • Very similar in spirit.

  • COLTON OGDEN: We have a couple of comments there too.

  • Pick 9117 says the target audience of this channel are not used to NPM yet.

  • It's going to kind of vary.

  • I think we likely will go into a lot of videos

  • in the future that are for people that are used to NPM,

  • but I'm assuming that today's video relies on no prior knowledge of NPM.

  • This is more of a--

  • I mean, I guess you can develop React with NPM,

  • but I think this is just like a from scratch tutorial.

  • BRIAN YU: Yeah.

  • In fact, it is probably more conventional to design React apps using

  • something like Node and NPM, for instance,

  • in order to manage your packages.

  • We're doing it this way in just a static HTML file for now

  • just to make it easy to follow for people that don't have that installed,

  • for instance.

  • But if you are interested in the probably more conventional way

  • to do this, take a look at Create React App,

  • which is a way of just creating a sample react app just

  • from scratch that uses NPM, for instance,

  • in order to install and manage dependencies and packages.

  • That tends to be the way that people will conventionally

  • start building a React front end nowadays if they want to.

  • This just happens to be another way to do it

  • that's a little bit simpler if you don't have that background, for instance.

  • COLTON OGDEN: [INAUDIBLE].

  • Nuanda 3333.

  • You explain everything thoroughly.

  • Thanks a lot for that.

  • Easier to follow.

  • BRIAN YU: I'm glad you're finding it easy to follow.

  • React can definitely be challenging at times, so not to worry if some of this

  • seems complicated.

  • There are a lot of resources out there available

  • on the internet to help you out there.

  • COLTON OGDEN: And Bavick Knight wants clarification.

  • So super is the react.component, right, the superclass?

  • BRIAN YU: Exactly.

  • The react.component is the superclass, and so super refers to that.

  • Precisely.

  • COLTON OGDEN: Awesome.

  • BRIAN YU: All right, so we've extracted the first number from the state

  • and put it in the first part of the addition.

  • And as you might guess, the analog here is

  • with the second number in this addition problem, this plus 1,

  • rather than the other plus 1.

  • I'm going to say this.state.num2.

  • So now instead of hard coding 1 plus 1, I'm saying extract Num1 from the state

  • and then do plus, extract Num2 from the state,

  • and we're going to display that instead.

  • So now if I go back to the page and refresh the page,

  • you'll notice it stayed the same.

  • Nothing changed.

  • We added a whole bunch of code and we didn't see any noticeable result.

  • But the idea here is that now these numbers 1 and 1

  • are being drawn from the state of my component

  • rather than just being hardcoded into the HTML of the page,

  • such that later on, if I were to change the state,

  • if I change Num1 to be 27 for instance, and I save that and I refresh the page,

  • now it's, OK, 27 plus 1.

  • Just by updating the state, I've been able to update

  • what it is that the front end of my web application

  • is ultimately going to look like.

  • COLTON OGDEN: I'm guessing you can make a component that takes input 2

  • and then changes the state as a result of that.

  • BRIAN YU: Yeah, certainly.

  • So if you want a component that takes the input right at the start,

  • that's generally done through the props of that component,

  • and so you can do that as well.

  • So all right.

  • We've defined this problem, and it's going to define Num1 plus Num2.

  • And now we also need some place where we can begin to type in the answer

  • to this.

  • So underneath this div, let me define an input field.

  • And this input field, right now I'm just going to say,

  • OK, it's just an input field.

  • That's it, where the idea is going to be this

  • is going to be the place where the user playing this game

  • is going to type in the answer to this addition problem, for instance.

  • So if I refresh the page after adding that input field, here it is.

  • Here's my new game.

  • I've got 1 plus 1 up at the top, and I've got this input field down

  • at the bottom.

  • COLTON OGDEN: Can you read that last comment there in the Twitch chat?

  • BRIAN YU: 10 plus 1.

  • So anyone who wants to know what 10 plus 1

  • is, it's a joke for people that have been keeping up with CS50's lectures

  • here on campus for fall 2018.

  • The 10 plus 1, it comes up at one point in time.

  • So if you haven't seen those lectures, you might-- oh, that's David.

  • COLTON OGDEN: Shout outs to [INAUDIBLE] for joining us on Twitch today.

  • You can read that last one too, if you want.

  • BRIAN YU: What configuration software do you use to record the video?

  • [INTERPOSING VOICES]

  • COLTON OGDEN: So we use Streamlabs OBS software.

  • We have a full production setup.

  • Mr. Dan [INAUDIBLE] is actually here in the studio.

  • Now, do you want say hi on camera, Dan?

  • Our cameraman, our production staff.

  • SPEAKER 3: Hello.

  • COLTON OGDEN: Actually, why don't you answer the question?

  • What do we use to record the video besides Streamlabs.

  • SPEAKER 3: The camera we're using is a Sony A7S

  • with a Canon [INAUDIBLE] millimeter mark 2 lens, I believe.

  • We have a PC with the streaming software set up, which you talked about.

  • And otherwise, we have some simple lights hanging up

  • on that green screen in the back.

  • Pretty simple setup.

  • COLTON OGDEN: And what are you going to be on here next Tuesday to talk about?

  • SPEAKER 3: Next Tuesday, join us for a little bit of Paper.js, and maybe some

  • Hammer.js as well, the underlying components of Draw 50.

  • Should be fun.

  • COLTON OGDEN: Nice.

  • Yeah, the software that David uses to actually draw in the lecture,

  • like a digital chalkboard, so.

  • SPEAKER 3: And I'm here just to check on Brian's microphone, so excuse me.

  • COLTON OGDEN: Oh, OK.

  • Hopefully we didn't screw it up.

  • BRIAN YU: Working OK?

  • All right, sounds good.

  • All right, so we now have this these two numbers, 1 plus 1,

  • and plus an input field where I can begin to type what I think

  • is the answer to this problem.

  • And so at this point, we have a new piece of state

  • that we want to keep track of inside of this web application.

  • In particular, we want to keep track of what it is that the user has typed in,

  • because that's technically part of the state of the application,

  • but part of the state of this component is knowing what the user's typed in,

  • because ultimately we're going to want to check that against whatever

  • the actual answer to the addition problem is.

  • So let me go ahead and add something to the state of this application.

  • In addition to keeping track of Num1 and Num2, the two numbers that I'm

  • going to try to add, I'm also going to add to the state

  • a response, which is going to start out being the empty string meaning

  • by default, there should be nothing in the input field, no response.

  • But this response is going to be the part of the state that

  • keeps track of what it is that the user has actually

  • typed in into this input field.

  • And now I'm going to go down to this input field,

  • and I'm going to say that the value of this input field

  • is going to be this this.state.response In other words, whatever

  • it is that is inside of this.state.response,

  • that is going to be what gets filled in into the input field.

  • So now if I refresh the page, 1 plus 1 plus the input field,

  • nothing's changed just yet.

  • There's nothing in the input field because the response by default

  • is the empty string.

  • But if I wanted to change that, for instance, if I went back here

  • and I changed the response to be like Hello by default,

  • for instance, and refresh the page, well now, OK,

  • hello shows up in the input field because whatever this.state.response

  • is, that's what gets filled in into this input field.

  • But it should be empty just to begin with.

  • An interesting side effect is, and maybe you

  • won't be able to tell this because the keyboard's behind the camera,

  • but I'm going to try typing something right now.

  • I'm going to try and type numbers, and what Colton at least can notice

  • is that as I'm typing numbers, nothing is actually

  • showing up in the input field.

  • COLTON OGDEN: Verified.

  • BRIAN YU: Yeah, and so this seems like--

  • COLTON OGDEN: He's not lying to you.

  • BRIAN YU: A little bit of a strange thing,

  • as you might expect, right, input field, I start typing things into it.

  • Things should start appearing, but nothing's appearing.

  • The input field is still blank, and so that's

  • sort of a strange quirk of React.

  • Why might that be?

  • Well, it turns out if we look back at the code, look at what we've said,

  • we've said whatever is contained inside of this.state.response, that should

  • be what shows up in the input field.

  • And this .state.response is always just the empty string.

  • It never changes.

  • We've never changed what it's equal to right here, and so as a result,

  • we're always seeing the input field as blank no matter what we try to type in.

  • And so what are we going to have to do here?

  • Well, we probably want some notion of, all right,

  • whenever we try to change the value of the input field,

  • let's go ahead and update this .state.response to reflect whatever it

  • is that the user's actually just typed in.

  • So let's do that.

  • In this input field down here, I'm going to say, onChange.

  • And notice the capital C just happens to be a React convention,

  • so onChange with a capital C is how we're going to say,

  • when the input field's value changes and then I try to type something

  • in, for instance, let's go ahead and call a function.

  • And what function do I want to call?

  • I'm going to call it this.updateresponse.

  • It could be called anything, but Update Response feels like a reasonable name

  • to give it just for now.

  • Now what is-- I haven't defined Update Response yet, so let me go ahead

  • and do that.

  • Down underneath the render function, let me define an Update Response,

  • which is going to be equal to--

  • and here I'm going to use an ES6, the latest version of JavaScript

  • specific feature, known as arrow functions, which are just

  • another way of defining what a function is,

  • and I'm saying that this is a function that's going to take in as its input

  • the event, the event of me actually typing something in, trying

  • to change the value of the input field.

  • And when I get that input of the event, here's what I'm going to do.

  • So the arrow is saying the input is the event,

  • and here is the body of the function itself.

  • And now here is what I'm going to do.

  • I'm going to update the state of my application,

  • and to do that, React has a special function called this.setstate.

  • And I'm going to set the state, and in particular, I'm

  • going to set the response equal to something.

  • Remember, response is the part of the state that

  • corresponds to what the user has typed in,

  • and in JavaScript, what you may or may not be familiar with,

  • the way to take an onChange event and extract

  • the thing that's actually been typed in is

  • to set it equal to event.target.value.

  • The event is the actual change event.

  • I tried to change the value of the input field.

  • Its target is, OK, what was I trying to change.

  • It was the input field.

  • And what is that input field's value, meaning

  • what did I actually try to type in?

  • That's going to be the thing that I should update my response to be now.

  • COLTON OGDEN: Gossen says, why do you talk about states whereas you

  • have likely declared variables just like the response variable.

  • What's the meaning of the word state?

  • BRIAN YU: Yeah, good question.

  • So state you can think of as sort of like a variable,

  • but before React and before the React-like user interfaces,

  • if I had some state, some variable, that was keeping track of information

  • about my application, and I wanted that reflected inside of my actual web page,

  • I would need to first update the variable,

  • update my state, so to speak, and then also run

  • a command that would actually take the value of the variable

  • and like update the HTML.

  • So you might be familiar with like updating the inner HTML of an element,

  • for instance, if you've use JavaScript before,

  • like take the value of a variable and put it inside of a particular HTML

  • element, for example.

  • What React is going to allow us to do is not

  • need to worry about any of that, where the idea is going

  • to be our interface is going to update itself dynamically,

  • reactively, based upon the state.

  • So the idea here is that on line 35, when I set the state

  • and update what the value of the response

  • is, that's going to result automatically in my user interface

  • updating what value is in the input field without me needing to say,

  • all right, grab the input field, let me update the value there

  • and insert something there.

  • Everything is just going to respond to that state.

  • And you might imagine that in a more complicated user interface, where

  • multiple different parts of your user interface dependent

  • upon the same piece of state, it becomes a whole lot easier,

  • because you update the state once, and anywhere in the user interface

  • where that user interface is dependent upon that piece of state

  • will update automatically.

  • And so we'll see examples of this, and you'll

  • start to see how this is powerful as we continue to build out

  • this particular application.

  • Good question, though.

  • COLTON OGDEN: Bavick also said input is like setters I guess, using a setter.

  • BRIAN YU: Input in this case is just an HTML element.

  • So when we're describing the structure of a web page,

  • we can use HTML elements like div to define a particular section

  • of the page, an input in this case, to mean this is a part of the HTML page

  • where we can begin to type something in, for instance.

  • So all right.

  • We just added this update response function that gets

  • called whenever the input field is changed.

  • Let me go ahead and go back here, refresh the page.

  • Nothing seems to be different, but now if I try to type something in, 1 plus 1

  • is 2.

  • All right.

  • Great.

  • Now when I typed it in, that updated inside of the state

  • what the response is, and we're seeing it right there.

  • And in fact, I can prove this to you that it's actually updating the state

  • and showing the response by adding a little bit of extra code

  • that I'm going to delete in just a moment.

  • But let me add another div where I say, for instance, that the response is

  • this.state.response, where I'm just effectively printing out

  • what the current value of this.state.response

  • is right now, for instance.

  • COLTON OGDEN: Twitch Hello World says, thank you

  • for starting with a static site.

  • Is there a book that covers this to refer to later, by chance?

  • BRIAN YU: A book that covers this.

  • I wouldn't necessarily recommend or refer you to a particular book,

  • because libraries like React are always updating.

  • React is constantly being updated with new features, features

  • that are coming and going, and so by the time that a book is published,

  • odds are that a lot of the things that are described in it

  • are already going to be out of date.

  • But there are a lot of online resources with regards to React.

  • You can look to Facebook's own React documentation for a lot of tutorials

  • and guidance on how to do this sort of thing,

  • and many other people out there on the internet

  • have also put out tutorials for how to do particular things with React,

  • so a lot of great online resources there even if there

  • aren't any good books on the subject, at least not that I'm aware of.

  • COLTON OGDEN: Probably a lot of YouTube videos too.

  • BRIAN YU: Yeah, I'm sure plenty of YouTube videos.

  • COLTON OGDEN: The blue's a little bit hard to read,

  • but it's Andre Pedalin, who's on our Facebook if you're familiar.

  • BRIAN YU: Oh, yeah.

  • Yeah.

  • COLTON OGDEN: He says, hi, Brian and Colton.

  • So the argument to this set state is the JSON object?

  • BRIAN YU: Yeah, you can think of it like a JSON object.

  • Really, you can think of in this case as specifically a JavaScript object, which

  • looks very much like a JSON object would look in this case.

  • So all right.

  • I've added this response is this.state.response,

  • and now you can really see what I mean.

  • Right now, response is nothing, but if I start to type something like 2,

  • my user interface is automatically updating anytime I type

  • or remove a character, because whatever I type in

  • is becoming part of the state.

  • And because whatever after its response is is just

  • referencing that state, whenever the state changes,

  • my web application is updating dynamically in response to it as well.

  • So I'm going to get rid of that because I don't actually

  • want that in the application, but that's just

  • to show you this.state.response is actually updating

  • anytime my input field is changing.

  • So all right, I'm on my way to starting to build this game.

  • I'm able to see a math problem now.

  • I'm able to type an answer.

  • And what I'd like to do is, you know, when I press Return

  • or Enter on my keyboard, I'd like for that

  • to mean like, OK, submit my answer.

  • But right now I'm pressing Return and you know,

  • nothing's happening right now.

  • So let's add a new event handler.

  • Let's handle the case when the user presses the Return

  • or Enter button, and do something interesting in that case.

  • So go back here.

  • In addition to input onChange, let me add one that says onKeyPress.

  • In other words, whenever I press a key.

  • There's no particular event for pressing the Enter or Return key specifically,

  • but there is an event for saying when I press a key.

  • And what I'm going to do is, so again, when I press a key,

  • let me check what key I pressed, and if that key is the Enter key,

  • then let me go ahead and do something interesting.

  • So onKeyPress, I need a function here.

  • I'm going to call it this.inputKeyPress, for instance,

  • but I could, again, call it anything.

  • And let me now define that function.

  • The input key press is going to be a function that takes an event as

  • with before, and first does a check.

  • If the event.key is equal to Enter, well then that

  • means the user pressed the Enter key, and I should do something interesting

  • now in response.

  • So what am I going to do?

  • Well, let me first actually get what the user's response is,

  • and to save that instead of a variable called Answer.

  • And I'm defining it as a const, meaning a constant variable,

  • meaning this variable is not going to change

  • at least for this particular invocation of the function.

  • And it's going to be equal to--

  • well, where is the user's answer stored?

  • Well, what the user typed in, that's stored in this.state.response.

  • But there's a small nuance here in that what the user types into the input

  • field is a string.

  • It's text that the user's typing into that input field.

  • And the answer to an additional problem shouldn't be text,

  • it should be an integer.

  • And so I want to, in JavaScript now, take this text,

  • covert it into an integer, and the way I'm

  • going to do that is by using a function built into JavaScript

  • called parseint, which is going to take in this case this.state.response,

  • and it's going to convert it into an integer.

  • I see that someone's a little bit confused about the triple equal sign

  • and what that means.

  • This has to do with JavaScript equality, that there are technically

  • a lot of things that could be equal to each other by a double equal signs,

  • even if they're not strictly speaking equal to each other.

  • The triple equal sign is going to strictly check just

  • to make sure that they're equivalent.

  • In this particular case, double equal sign probably

  • would have worked just fine, but convention in JavaScript or good design

  • practice is, when you can use the triple equal sign, indeed to do so.

  • So I've defined this variable called Answer,

  • which is what it is that the user has typed in to the input field.

  • And now what I want to do is, I want to check to see whether or not

  • the user got the answer right or not.

  • Did the user get the answer right?

  • And so how might I check that?

  • Well, all right.

  • I'm going to run an If condition.

  • I want to check if Answer is the sum of the two numbers

  • that are in the problem.

  • And now where were the two numbers in my problem stored?

  • Well, if we think back, it was really stored in this.state.num1,

  • and I want to check if Answer is equal to this.state.num1 plus

  • this.state.num2.

  • In other words, did the user correctly get

  • an answer that was the sum of the two numbers

  • that were presented as the problem on the screen?

  • And so if the answer was correct, well, what do we want to do?

  • Well, what I want to do is I want to set the state of my application,

  • and I want to give them a new problem.

  • I want to give them a new Num1, and I want

  • to give them a new Num2 because they got the answer right.

  • Let's give them a new problem to work on.

  • So in this case, I'm going to say, all right, Num1 is going to be what.

  • Well, I want it to be some random value, and so JavaScript

  • has a function called math.random.

  • Math.random is going to get me a random number between 0 and 1.

  • Probably not too interesting if those are the only numbers I'm dealing with,

  • so let's deal with things a little bit bigger.

  • If I do math.random times 10, that's going

  • to give me a random number between 0 and 10 or 0 and up to,

  • but not including 10, for instance, in this particular case.

  • So I've got a random number, but this could be a floating point number.

  • I might get something like 3.

  • In fact, I probably will.

  • There's something like 3.28574 something something.

  • But what I really want, this is just going to be a beginner's edition flash

  • card program, is not to have this be a floating point number,

  • but for it to be an integer, for instance.

  • And so the math operation I'm going to use here

  • is math.ceil, meaning math.ceiling, and the ceiling

  • of a number that has a decimal is just take the next highest number.

  • So if the number is 3.28, the ceiling of that

  • is just going to be, take the next integer that's higher than that,

  • in this case, 4 for instance.

  • And so this is going to get us a number from 1 to 10,

  • for instance, just some randomly chosen number

  • that we want to be the next Num1.

  • COLTON OGDEN: [INAUDIBLE] says, the triple equals

  • is because JavaScript is three times cooler.

  • Can you verify that that's true?

  • BRIAN YU: You know what?

  • I wasn't the person who designed the triple equal sign,

  • but maybe that was part of it.

  • Who knows?

  • Num2, meanwhile, is going to be the same thing.

  • I also want it to be a random number between 1 and 10,

  • so I'm going to set it to be the ceiling of math.random times 10.

  • This is a conventional way, not just JavaScript specific,

  • but oftentimes programming languages will give you

  • a way of getting a random number between 0 and 1,

  • when realistically what you want is a random integer in some other range.

  • And so knowing how to do the multiplication and maybe

  • addition in order to shift your random floating point number between 0 and 1

  • to the range that you want is often a useful trick

  • to be able to use if you want to generate a random number.

  • And so this is what I'm going to do.

  • If the answer is correct, then update the state of my web application.

  • Update Num1 to be some random number, and update

  • Num2 to be some random number as well.

  • So let's give this a try.

  • Assuming I did everything right, I'll refresh the page.

  • We have 1 plus 1.

  • If I get the answer wrong, if I type in 3, for instance, then I press Return,

  • well, all right.

  • Nothing happens.

  • And that's to be expected, right.

  • Nothing happens because what I typed in, 3, is not correctly the sum of 1 and 1.

  • But if instead I type in 2, which is the correct answer, and I press Enter,

  • watch what happens, hopefully.

  • All right.

  • I press Enter and the problem changed.

  • It changed to 8 plus 1.

  • COLTON OGDEN: If that changed back to 1 plus 1 again out of randomness.

  • That would have been fun.

  • BRIAN YU: It would've been possible for it to change back to 1 plus 1 randomly,

  • but in this case, it did in fact change to something else.

  • It changed to 8 plus 1 by generating new random numbers in this particular case.

  • So why did that happen?

  • Well, if we go back to the code, when the input key was pressed,

  • we check to see if the key was the Enter key.

  • It was.

  • We calculated what the answer is by taking what the user typed in,

  • passing it as an integer, in that case 2.

  • We checked to see if the answer was equal to the sum of the two numbers.

  • 2 is equal to 1 plus 1.

  • Yeah, it is.

  • And since it was, we updated the state to reflect two new numbers.

  • Now there's a user interface suboptimality here,

  • something that's not quite great about the way this user interface works.

  • And I'm sure that you saw it if you saw me do it.

  • I'll do it again if I try and get this answer right.

  • If I type in 9, getting the answer right, and I press Return,

  • I get a new problem, but in my input field, the 9 is still there.

  • Probably not what I want, because probably I want an opportunity now

  • to type in something new.

  • So how do I fix this?

  • Well, in reality, this becomes pretty simple.

  • This 9 is only there because 9 is the current value of this.state.response.

  • It's the current value of the response inside of the state of my current React

  • component.

  • And so if I want to clear out the text field anytime the user gets the answer

  • right, well, let me go ahead and say, all right, Num1 gets a random number.

  • Num2 gets a random number.

  • But let me also update the state's response,

  • and just set it to be the empty string again, in other words,

  • clear out the response if the answer is incorrect.

  • COLTON OGDEN: Do you want to start about halfway down the chat?

  • Twitch Hello World has a question for you.

  • BRIAN YU: Yeah.

  • Let me show this real quick and then we'll answer the questions.

  • So if I refresh this now, 1 plus 1, I type in the correct answer, 2,

  • and when I press Return, I get a new problem and the input field clears out.

  • So much better user interface from the perspective of the person using it,

  • because now you can actually type in another answer, press Return

  • and you get a brand new problem.

  • And so that's definitely a whole lot better.

  • COLTON OGDEN: We shouldn't show this one to David.

  • He probably wouldn't get it right.

  • BRIAN YU: All right.

  • Twitch Hello World asks, does math.random

  • generate a pseudorandom number.

  • Yes, math.random generates a pseudorandom number between 0 and 1,

  • and that's the way most random number generators ultimately are working.

  • COLTON OGDEN: And Nuanda says, aren't they all sort of random.

  • Andre, I think he's making a point about being

  • able to visually see the difference in double equal and triple equals, which

  • you do in a terminal.

  • BRIAN YU: Yeah.

  • We can show this right now, actually, if people are curious.

  • If I go into the JavaScript console and I

  • can just open up the inspector to see it.

  • COLTON OGDEN: Turned the chat off there for you.

  • BRIAN YU: Oh, yeah.

  • Great.

  • Thank you.

  • If I do something-- what is the example there?

  • If I do 1 equals equals the string 1, press Return, all right,

  • that's technically true.

  • So you can see this double equal sign is doing a bit of a loose equality.

  • Yeah, 1 is basically the same thing as 1,

  • and it's a little more flexible in what it counts as equality,

  • whereas this triple equals is a strict equality.

  • Is the integer 1 equal to this string 1?

  • Well, that's ultimately going to be false,

  • because no, those are different things.

  • One of them is an integer.

  • One of them is a string.

  • You can likewise see this if I check, is 0 double equal to false, for instance.

  • That's true.

  • 0 and false are both falsey values in the world of JavaScript, so

  • double equal sign, those compare as equal.

  • But 0 triple equal sign false, for instance,

  • that's false, because the number 0 is not strictly equal

  • to the Boolean value false.

  • And so the triple equal sign gives us a slightly different result, and so just

  • for precision's sake, I'm using the triple equal sign

  • where it's appropriate to do so.

  • COLTON OGDEN: Would you say this flexibility

  • is a reason for some of the weird sort of type coercion bugs

  • that are topics of like the [INAUDIBLE] talk for example?

  • BRIAN YU: Yes, definitely.

  • You should definitely go take a look at those talks

  • if you haven't already seen it, but it's amazing

  • the things, the sort of strange features of the JavaScript type system,

  • where because of the way the type system works

  • you can get it to behave in very strange ways

  • that you might not initially expect.

  • But definitely some funny talks out there about that subject

  • if that's something that's interesting to you.

  • COLTON OGDEN: Twitch Hello World.

  • I heard there is no such thing in CS as genuinely a true random number, though,

  • Haven't verified exactly.

  • That's correct, right?

  • BRIAN YU: Yeah.

  • Computers can really only do, can only follow the instructions that they

  • are given, and so really what ultimately happens in order

  • to generate a random number is that the computer is doing

  • a whole bunch of mathematical operations to generate a number that feels

  • random to us, and that follows the expectations of a random number,

  • like it will be distributed randomly across a range.

  • But that ultimately might not actually be truly random,

  • and the question of what truly randomness is

  • is an actually really interesting question, not only in computer science

  • but in math and philosophy as well.

  • The technical term for that is stochasticity,

  • so feel free to look into that if that's something interesting to you as well.

  • COLTON OGDEN: Meal Eagle looks like he has a question addressed strictly

  • to you if you want to read that one off.

  • BRIAN YU:

  • SPEAKER 3: Yeah.

  • Is it more user friendly if you enter an incorrect answer,

  • there is a visual indication that you got it wrong?

  • Great question.

  • That is definitely the case, because right now if I get an answer wrong,

  • 10 plus 9, if I think the answer is 11 for instance, and I press Return,

  • nothing happens, and that's probably not the best user interface.

  • So definitely improvement that we can make there, and in a couple minutes

  • we'll go ahead and make that improvement just

  • to make the interface a little bit better if the user does,

  • in fact, get the answer wrong in this case.

  • COLTON OGDEN: Gossen says, in case of a non-integer input,

  • does the instructions throw an exception,

  • because frankly, I see that it's based on Java philosophy just taking

  • advantage of the web scripting.

  • BRIAN YU: Yeah, good question.

  • So if I type in a text, like hello, for instance,

  • you'll notice that nothing quite happens, and that is a good question.

  • So it looks like it's never going to be the correct answer if you type in text,

  • because the answer is not going to be equal to Num1 plus Num2.

  • I can't remember exactly how parseint is handling it.

  • I actually thought it was going to throw an error, but interestingly--

  • COLTON OGDEN: You could probably console, parsing it hello.

  • BRIAN YU: Yeah, that's a good idea.

  • Parse it hello.

  • It returns NAN, which stands for not a number, which is what you might expect.

  • COLTON OGDEN: The Batman part of the [INAUDIBLE] talk.

  • BRIAN YU: Indeed, yup, if you're seen that talk.

  • And indeed, NAN, not a number, is not going

  • to be equal to the sum of these two numbers,

  • so it's actually fine in this case to just use parseint.

  • Good question.

  • COLTON OGDEN: And Bavick Night says, Java is weird as well.

  • String 1 plus 1 is 11 with the default string concatenation

  • being the plus operator.

  • Twitch Hello World, I might not remember accurately,

  • but I thought you said a number less than 10 would be generated.

  • Did you change this in the second step?

  • I thought maybe the pseudorandom number generator was between 0 and 1, maybe.

  • BRIAN YU: Oh, question.

  • So yeah, it's not going to generate the number 10,

  • but it could generate a number like 9.5, for instance.

  • And if it generates 9.5, and then I take the ceiling of that number right here

  • in math.ceil, the ceiling of 9.5 is ultimately going to bring 9.5 up to 10,

  • and so that's how I'm able to get a number ultimately between 1 and 10

  • in that range.

  • COLTON OGDEN: Looks like Bavick just chimed in with that same detail there.

  • BRIAN YU: Yup.

  • Good observation.

  • COLTON OGDEN: Awesome.

  • BRIAN YU: So all right.

  • I forget, it was Metal Eagle who mentioned it.

  • The way that we handle an incorrect answer right now

  • is not ideal, right, because right now, if I enter an incorrect answer, 10

  • plus 9, I type in 11 for instance, I press Return, nothing happens.

  • So what should happen?

  • Well, I feel like at minimum, we should clear out the response field

  • just as we did before to give the user an opportunity

  • to try again, for instance.

  • So let's do that.

  • If the user got the answer right, then we're setting the state, but else,

  • if they got the answer wrong, well, let's do something interesting

  • there too.

  • Let's say this.setstate, and let's just for now

  • set the response equal to be the empty string.

  • In other words, clear out the response, because we

  • want to clear out the input field such that the user can now

  • type in some new answer.

  • So go ahead and run this application again.

  • 1 plus 1.

  • I type in 2.

  • I got that right.

  • 9 plus 8, let's say I struggle with this a little more.

  • The correct answer is 17, but instead I typed 16, for instance.

  • And I press Return.

  • Input field clears out, but I don't get a new problem,

  • because I didn't update Num1 and Num2 in this state.

  • Those are still the same thing, and just clearing out

  • the input field such that now I can actually type in the correct answer,

  • press Return and get a new problem there.

  • COLTON OGDEN: We need like a really obnoxious buzzer

  • sound when you get it wrong.

  • BRIAN YU: Yeah, so we could add sounds in,

  • a little bit fancier than we'll do here, but I think at minimum we

  • can do some UI improvement.

  • Like if I get the answer wrong, right now it clears out the input field,

  • but maybe let's try and say, let's get this problem field to turn red,

  • for instance, when I get the answer wrong,

  • because that might be a visual indication that all right, I

  • got the answer wrong.

  • Input field cleared out and the text turned red.

  • So let's try and do that as well.

  • So now how am I going to go about implementing this?

  • Well, the first thing to realize is that whether or not

  • the user got the answer wrong, that's going

  • to be part of the state of my application, you might imagine,

  • that by default I didn't get the answer wrong,

  • but you might say later on, if I do get the answer

  • wrong, that's going to change the state of my application

  • because I want my UI to reflect the fact that the answer was wrong by turning

  • the text red, for example.

  • So up here, when I initially define the state

  • of my application up in the constructor, let me add a new part of the state

  • that I'm going to call like, Incorrect.

  • Did the user get the answer incorrect?

  • And when the game first starts, they haven't yet gotten anything incorrect,

  • so Incorrect by default is going to be false.

  • So all right.

  • Now when the user gets an answer wrong, in addition

  • to setting Response to be equal to the empty string,

  • let me also set Incorrect to be equal to true.

  • I'm updating the state such that this Incorrect value is now

  • going to be equal to true.

  • Now, how am I going to style the web application?

  • I'm going to turn the text read if the user got the answer wrong.

  • COLTON OGDEN: My first inclination would be CSS.

  • BRIAN YU: CSS is a great inclination, actually.

  • In fact, let's try this right now.

  • What you might do is up here, in my application in the header,

  • I might define some style, and you might want to move this to a separate file

  • just to separate things out.

  • But for the sake of example here, we'll just put it in one place.

  • And maybe let's define a class called Incorrect.

  • And the dot in CSS means if something has a class of Incorrect,

  • well, let's go ahead and change the color to red, for instance.

  • And that might be what we do.

  • If something has a class of Incorrect, the color is going to be red.

  • And we can test this now.

  • If I go down here to my problem where I have Num1 plus Num2, and I say,

  • let's give this ID a class, and in React,

  • because the word class is already used for like Class app,

  • the way we define a class using React is to call it a class name, technically.

  • And let me set class name equal to the JavaScript string Incorrect.

  • So if I set the class name to be Incorrect,

  • plugging in the JavaScript string there--

  • COLTON OGDEN: And a question.

  • Why is it in curly brackets there instead of the like ID equals?

  • BRIAN YU: Because I'm inserting a JavaScript value here.

  • It'll be clear in a moment why I'm doing that.

  • Now if I refresh the page, we see that the text has indeed turned red.

  • We get 1 plus 1 in red there.

  • Is that showing up on the--

  • COLTON OGDEN: It's red, yeah.

  • Yeah.

  • BRIAN YU: It is red?

  • OK.

  • It shows up on my screen as red, at least.

  • COLTON OGDEN: TV color isn't the greatest, I don't think.

  • BRIAN YU: Oh, OK.

  • So 1 plus 1 is red, which works.

  • I was able to use CSS now to change the color of the text of the problem,

  • but this isn't quite right, because 1 plus 1 is red from the get go,

  • and I only want it to be red if the user got the problem wrong.

  • So what I'm going to do here, I'm going to use some JavaScript

  • logic here inside of the class name.

  • In other words, I don't want the class name to always be incorrect.

  • I only want the class name to be incorrect if the user actually

  • got the answer wrong.

  • In other words, if the Incorrect part of the state is equal to true.

  • And so to do that, I'm going to use what's called

  • the ternary operator in JavaScript.

  • It's very similar to the ternary operator in C or Java

  • if you've used it in other languages.

  • But basically, I'm going to ask myself the question, this.state.incorrect, did

  • I get the answer wrong?

  • Is the value of Incorrect in the state true?

  • If it is Incorrect, if the user got the answer wrong,

  • then the class should be Incorrect, but otherwise, we'll

  • go ahead and just use the empty string.

  • In other words, don't give it a class name

  • if the user didn't get the answer wrong.

  • COLTON OGDEN: Makes sense.

  • So any time you use curly brackets, basically if you want

  • to do any sort of programming logic.

  • BRIAN YU: Exactly.

  • Any JavaScript programming logic, that's going to go in the curly braces.

  • And so here I'm adding some logic saying, don't always

  • give this div this class of Incorrect.

  • Only give it that class if the answer is in fact wrong.

  • And so let's see what the result of this is.

  • I refresh the page.

  • 1 plus 1 shows up, and 1 plus 1 is in black text, which is to be expected.

  • If I get the answer right, input field clears out.

  • I get a new problem.

  • Same thing if I get it right again, input field clears out.

  • 2 plus 5, the answer is 7.

  • But if I get it wrong, if I type in 8 for instance, and I press Return,

  • watch what happens.

  • Two things happened.

  • Input field cleared out, and the text now

  • turned red because I updated the state.

  • Incorrect is now true, and as a result, this div gets that class of Incorrect.

  • And according to my CSS code, that's going to style it as red.

  • COLTON OGDEN: And so now if you get it right again.

  • BRIAN YU: Now, OK, so here's an interesting bug.

  • If I get the answer right, I type in 7, what's going to happen?

  • Well, this is the right answer.

  • I expect myself to get a new problem.

  • I expect the input field to clear out.

  • I expect the text to turn black.

  • I press Return.

  • COLTON OGDEN: Oh, it didn't clear.

  • BRIAN YU: It cleared out and I got a new problem, but the text stayed red.

  • It's still red.

  • It still thinks I got the answer wrong.

  • Why is that?

  • Well, it's red based on the value of this.state.incorrect,

  • which starts out as false, and we set it to true

  • down here if I get the answer wrong.

  • But in particular, we never reset it if I get the answer right,

  • and so this is where the bug is.

  • So when I get the answer right, I want to also say, all right,

  • now the answer is no longer incorrect.

  • Incorrect is false.

  • We can go ahead and show up the text as black again.

  • Yeah, exactly.

  • So I'm going to refresh the page, get 1 plus 1.

  • I get the correct answer, 2, get a new problem,

  • get the correct answer again, get a new problem.

  • If I get the answer wrong, type in 7 for instance, press Return, all right, text

  • turns red now, and the input field's cleared out.

  • But if I get the answer right again, now I get a new problem and the text

  • turns back to black, so that's what I expected it to.

  • COLTON OGDEN: Twitch Hello World says, thank you so much.

  • I have to see the rest later.

  • I have to run.

  • Thanks, Twitch, for joining us.

  • I'll catch you next time.

  • Catch you on Friday, hopefully.

  • BRIAN YU: Yeah, thanks for joining me.

  • All right, so at this point in time, we've

  • got a pretty functioning web application at this point.

  • We have a user interface where we display a problem that updates

  • dynamically, that generates new random problems every time the user gets

  • the answer right, and if the user gets the answer wrong, our UI reflects that.

  • Way it all turns red to indicate that the answer is wrong,

  • and once we get it right again, it changes.

  • And it's all based on it's a little bit of JavaScript state inside of our React

  • component.

  • The state is keeping track of the first number.

  • It's keeping track of the second number.

  • It's keeping track of the response, and it's keeping track of whether or not

  • I got the answer right or not.

  • And so certainly there are things that I can begin to do now.

  • Maybe I just want to make some aesthetic changes.

  • This has nothing to do with React specifically,

  • but I might say, all right, let's go ahead

  • and take my entire application and text the line [INAUDIBLE] it's centered,

  • give it a font family of sans serif.

  • This is just me making some UI improvements just

  • to make it look a little bit nicer, even though none of the actual content

  • is changing.

  • Let me take the problem and maybe give it

  • a font size of 72 point font just to make the problem bigger.

  • COLTON OGDEN: The background has some sports equipment, FRESHiAM style.

  • BRIAN YU: Yeah, something like that.

  • So now all right, now I've got centered text,

  • the problem is a little bit bigger, maybe

  • this is a little closer to what I want the ultimate web

  • application to be looking like.

  • But the missing thing, at least right now,

  • is I'd like to keep track of the user's score.

  • I'd like to keep track of, all right, how many questions

  • has the user gotten right.

  • So how am I going to go about doing that?

  • Let me go back here.

  • And the score, as you might guess, is also

  • going to be part of this component state.

  • Part of this application is not only going

  • to keep track of the response of what the two current numbers are,

  • but it's also going to keep track of what the user's current score is,

  • for instance.

  • And so inside of here, I'm going to add part

  • of the state that is equal to score, and score by default is just going to be 0.

  • Now I'll scroll down here, and underneath the input field,

  • let me go ahead and just say score.

  • And let me fill in the score into this part of the HTML page,

  • and I'm going to do that by saying, this.set.score

  • to mean, all right, let's display the score in this part of the HTML page.

  • COLTON OGDEN: Using Vim key bindings and VS code.

  • I would do something like that, says Bavick Knight.

  • BRIAN YU: Oh yeah.

  • I like the combination of VS code and Vim a lot.

  • There are a couple of good Vim extensions in VS code.

  • If you just go to the extensions page in VS code,

  • there are several good Vim extensions that work pretty well.

  • I think I'm just using the most popular one in this case, that

  • adds a lot of the standard Vim key binding support

  • into your VS code editor, and so that can definitely

  • be a helpful thing to do.

  • COLTON OGDEN: Do you or do you not also do it for Chrome?

  • BRIAN YU: Do I do it for Chrome.

  • Oh yeah, I also have a Chrome extension.

  • It's called Vimium, I think, that allows me

  • to use Vim controls in order to scroll through a website, for instance.

  • If I go to like the New York Times website, for instance, I can--

  • J in Vim means go down a line, for instance.

  • I can press J, which takes me down through the page.

  • K brings me up, for instance.

  • And so you can do that as well.

  • All right, so I've now defined score, and I've

  • tried to insert that score into the main part of this website.

  • Again, all of this is inside of this render function, this function that

  • runs any time that I try to load the contents of this particular component

  • such that now if I refresh the page, we see that I see

  • 2 plus 2, input field, and score is 0.

  • And all right, this isn't probably the greatest of user interfaces.

  • I probably want score to be on a line of its own.

  • Anything contained within a div is going to get basically a horizontal area

  • of the web page to itself, and so I'm going to surround score inside of a div

  • now, such that now I can say.

  • OK.

  • Score is 0, and that looks a little bit nicer.

  • And of course, there are UI improvements we can make here,

  • but for now this is going to work just fine.

  • I get a question right.

  • 1 plus 1 equals 2.

  • And the score stays 0.

  • So OK, that's not quite what I want.

  • What I want to do is, when I get the question right,

  • I want to update the state of my component.

  • I want to update the score to be whatever

  • the updated score should be, in other words, 1 plus

  • what the score was previously.

  • So the simple way to do that is down here, when I get the answer right

  • and I update the state to give myself two new numbers,

  • to clear out the response field, to say that I didn't

  • get the response incorrect, would be to also say,

  • score equals something in particular.

  • In this case, this.state.score plus 1 might be a reasonable way to do that.

  • And this would work.

  • If I went back here, refresh the page, 1 plus 1, I get the answer right.

  • I click 2, for instance.

  • I get it right.

  • All right.

  • The score updates.

  • I get a new problem.

  • Input field clears out.

  • The score is now 1.

  • I type 6, for instance, get that right, my score is now 2.

  • If I get the answer wrong, press Return, clears out, turns red,

  • score doesn't change because I'm not updating the score

  • state when I get the answer wrong.

  • Now you might imagine different game mechanics.

  • Maybe I want the score to decrease if I get the answer wrong, for instance.

  • You could do that too.

  • But for now I'm saying if you get the answer wrong,

  • just go ahead and don't change the score.

  • There is one minor design issue with this particular paradigm,

  • and this gets to be a little bit more advanced in terms of how React works.

  • But one interesting thing is that technically

  • speaking, when I say this.state.score plus 1

  • and set that equal to the new score, this opens me up to something called,

  • maybe not in this particular case, but doing something similar to this

  • in other React components, especially as your React applications get

  • more complicated, this does open me up to potential race conditions,

  • where the idea might be, if I'm evaluating

  • the value of this.state.score before the state has totally updated

  • or while someone else is trying to update the same state,

  • or some different part of the application

  • is also trying to update the state, there's a potential for conflict there.

  • And so there are many ways to deal with this,

  • but React actually has a pretty straightforward way of dealing

  • with this, and that's to say that right now, setState is taking as its argument

  • a JavaScript object, meaning here is the updates that you should

  • be making to the JavaScript state.

  • If I instead wanted to say, let's try and update the state

  • but make the new state dependent upon whatever the previous state was

  • in a way that doesn't open myself up to race conditions,

  • you can instead pass the this.setState a function,

  • a function that takes the state as an argument and returns

  • whatever I want the new state to be.

  • And then instead of this.state.score, I would just say state.score,

  • where this state refers to this argument to the function.

  • And so slightly more complicated.

  • The reason I'm doing this is just to be consistent with best React design

  • paradigms, in particular trying to avoid the potential for race conditions.

  • No worries if that was a little bit complicated.

  • SetState can also just as easily take a JavaScript object as well.

  • COLTON OGDEN: Bavick Knight was asking, you

  • have to set score as a class variable, right, instead of an instance variable.

  • BRIAN YU: In this case, this.state itself

  • is an instance variable that is going to contain

  • all of the parts of this particular component.

  • And you might imagine that if we wanted to,

  • we could create two of these games, for instance, running in parallel,

  • where each one had its own score, for instance.

  • We could do this right now, actually.

  • Instead of just div App, if I copy that and call this div App

  • 2, for example, and then down here at the bottom,

  • in addition to rendering the app inside of App,

  • I also rendered the app inside of App 2.

  • So now I only defined the class once, but I'm rendering it twice

  • in two different parts of my HTML page.

  • You might imagine that now, if I refresh the page--

  • why didn't that work?

  • COLTON OGDEN: Because your thing's just looking for just the App ID, right,

  • not App 2?

  • BRIAN YU: Target container is not a DOM element.

  • ID App 2.

  • COLTON OGDEN: Oh, I know.

  • That is your preselector.

  • BRIAN YU: Target [INAUDIBLE] is not a DOM element.

  • I'm not entirely sure why that's happening.

  • But let me try to get back to you on that one.

  • For now, we'll just try and render the application once.

  • COLTON OGDEN: Part of the fun of live coding.

  • BRIAN YU: Yep, indeed.

  • COLTON OGDEN: But the point, I guess, that we see,

  • is you wouldn't necessarily have just one app or whatever component.

  • It wouldn't want to be a static variable necessarily.

  • It's good to have it be an instance variable

  • so you could have multiple components running together.

  • BRIAN YU: Yeah, exactly.

  • And I wonder-- actually, let me try this one more time.

  • Let's see if instead of just rendering--

  • COLTON OGDEN: If it makes you feel better,

  • I messed up big time on camera like three times last stream.

  • BRIAN YU: No worries.

  • Let's try this and see if it'll work.

  • Let's render a div inside of which we're going to render App twice,

  • which we should be able to do.

  • If we refresh that, all right, great.

  • Now there we go.

  • Now we've rendered the application twice inside of this.

  • And you'll notice that each one of them is going to function independently.

  • If I get an answer right here, get an answer right, get an answer right,

  • get an answer wrong, I can have an independent score.

  • I have independent problems.

  • I have independent, did I get the answer right or not, running simultaneously.

  • Each one is just an instantiation of this App component,

  • and I can use that App component multiple times,

  • and each one is going to have access to its own state, for instance.

  • And so that's what's going on here, in order

  • to allow me to basically run the same thing multiple times.

  • COLTON OGDEN: Nicely done.

  • That was fast, too.

  • Cloud FF06 says, hey from South Africa.

  • Good to have you, Cloud.

  • Thanks for joining us today.

  • And Bavick Knight says, wow.

  • He's impressed too.

  • BRIAN YU: Glad we were able to get that working.

  • All right.

  • But we'll go back to just having one game

  • because that'll make things a little bit simpler just for our purposes.

  • But you can imagine that now you have this capacity of reusing components

  • if you wanted to create a multiplayer game, for instance, where people are

  • racing to see who can get to a particular score first,

  • that would be something you can do.

  • And that's one of the beauties of react components, which

  • is that you design them once.

  • They self-contain their own state and their behavior

  • and how they should behave, and you can then

  • reuse those components in other parts of your application wherever you see fit.

  • You can reuse them multiple times if need be, and all of that

  • goes to show just the power of what React allows

  • you to do using these components.

  • So all right, we're almost at the state place

  • where we basically have a complete application.

  • Maybe the last thing we'd like to do is allow the user to win this game.

  • Right now, this game could go on forever.

  • You could just keep answering questions again and again

  • and again, and you would never get to the end of this game.

  • Your score would just keep going up and up and up and up.

  • Maybe we want to say, all right, once you get to a score of 10, for instance,

  • we're going to allow you to win the game.

  • We'll just say, OK, you've won the game, game over,

  • at the point at which you get a score of 10.

  • How might we go about doing that?

  • One thing you might imagine doing is you might say, OK, well,

  • we could add a part to the state to say, all right,

  • have you won the game or not, and add that as something the state

  • is keeping track of.

  • But we really don't need that.

  • We can infer whether or not you've won the game based

  • on the existing values of the state.

  • And this is part of the React design paradigm, that I could add like a 1,

  • which is set to false, for instance, and when I get to a score of 10,

  • update 1 to be true, for instance.

  • But this is a duplication of state information,

  • technically, that all the information I need to determine whether or not

  • the user won is inside of the score or part of the state,

  • so I don't need 1 to be able to tell me that too.

  • And in fact, having both opens myself up to potential bugs,

  • like what happens if the score is 15 but 1 is false.

  • Those seem to be in direct contradiction with each other,

  • and so oftentimes, a good thing to do is, only keep around the state

  • that you actually need such that you can just infer what the rest of the state

  • should be based on the state that you have.

  • And so that's what I'm going to do here, just

  • infer whether or not you've won the game based

  • on what the current value of score is.

  • COLTON OGDEN: Gossen says, hey Colton, let's add some GUI

  • and turn it into like a Flappy Bird game.

  • I don't know if we'll have enough time for that on stream today,

  • but in my games course, we do look at Flappy Bird from scratch,

  • so I'll toss the link in the chat here as well.

  • BRIAN YU: Yeah, definitely another good course

  • to take a look at if game development is something that's interesting to you.

  • This is just going to be a very simple text based game,

  • but a whole lot more opportunities for game development,

  • and we have some lectures on them that Colton's

  • done to help you with that if you're interested.

  • COLTON OGDEN: Awesome.

  • BRIAN YU: So all right, thus far throughout the design

  • of our application, what the user interface's structure

  • has looked like has never changed.

  • The numbers have changed, the score has changed,

  • what the user's typed into has changed, but the structure of it, of OK, number

  • plus number, input field, score, that stays the same throughout the entirety

  • of the gameplay.

  • When the user wins the game, I probably want to clear out the problem,

  • clear out the input field, clear out the score

  • and just show some text that says you won,

  • for instance, which means that I can't just always render

  • this sequence of divs that are going to display the same thing

  • every single time.

  • And so here's what I might do instead.

  • What I might do is, inside of the Render function, rather than call this Render,

  • I'm going to call this function Render Problem as in this case,

  • I just want to render a new problem for the user to try and solve.

  • And at the end of the game, once the user's won the game,

  • there's going to be no need to call Render Problem anymore because there's

  • going to be no more problem to display.

  • The user's won the game, and we can go ahead and move forward and just display

  • a screen that says congratulations, you won.

  • Now, React doesn't natively understand what Render Problem is.

  • React still requires me to have some function called Render

  • that's going to return something.

  • You might imagine that I could do something like this, where I might say,

  • if this.state.score is equal to 10, then let

  • me return this.renderwin, which is a function that I've yet to define,

  • meaning if the score is 10, once I get to a score of 10,

  • go ahead and render some page that says, all right, you've one.

  • Else, go ahead and return this.renderproblem.

  • So what's the logic here?

  • The logic is, once I've reached a score of 10 and I've won the game,

  • we're going to call the Render Win function,

  • and that's going to decide what I render on the screen.

  • Otherwise, if I haven't yet reached a score of 10,

  • then I'm going to return this.renderproblem, which is going

  • to be the same thing that I did before.

  • This whole function is going to return to me

  • what it is that is the problem that the user needs to be solving.

  • COLTON OGDEN: Will you be doing error handling, i.e. random character insert?

  • BRIAN YU: Good question.

  • We actually handled random character insert as we talked about, a little bit

  • ago, you may have missed it, but the idea

  • is that if I type like a text character rather than a number

  • into the input field, then we might run into a scenario

  • where we're calling parseint on something that isn't an integer.

  • And as we found out by looking at the JavaScript console,

  • when we call something like parseint on something like Hello

  • that's not in fact an integer, what we end up getting

  • is not a number, a special JavaScript value that means it's not a number,

  • and that's actually OK.

  • We can just compare to see whether the sum is equal to that not a number

  • value, in which case it's not going to be equal,

  • and so that's going to be an indication that the number is invalid,

  • for instance.

  • COLTON OGDEN: I don't mean to put you too much on the spot,

  • but would this code be on GitHub, by chance?

  • Can be share it with people?

  • BRIAN YU: Yeah.

  • We can find a way to share this with you afterwards.

  • COLTON OGDEN: OK.

  • [INAUDIBLE] a link.

  • I'll put in the YouTube.

  • BRIAN YU: Yeah, we can do that.

  • COLTON OGDEN: On game one, you should shoot some particles

  • and play a fanfare sound.

  • BRIAN YU: Certainly, you could do that.

  • Probably beyond the scope of what we're going to be doing here today.

  • COLTON OGDEN: And [INAUDIBLE] says, hello, Brian.

  • Nice to see you on the Livestream.

  • BRIAN YU: Hello.

  • Great to have you with us today.

  • So all right, back to winning the game.

  • We've defined this Render Problem function,

  • but the function we haven't yet defined is

  • the Render Win function for what happens when

  • the user does in fact win this game.

  • And so let's go ahead and define that.

  • Down here, say, Render Win.

  • And when you win, let's return some div.

  • We'll call it a div whose ID is winner, and we're just going to say, you win.

  • And that's it.

  • So now let's try playing this game.

  • We get 1 plus 1.

  • I get the answer right.

  • Get the answer right again.

  • And we'll answer a couple of questions.

  • Got the same question twice in a row, which

  • can happen if you end up generating random numbers every time.

  • It's going to happen from time to time.

  • We could add some extra checking to make sure you get a distinct question

  • every single time if you wanted to.

  • That's certainly something we could do.

  • 3, 13, 14, and all right.

  • We got 10 questions right, and now rather than calling Render Problem,

  • we're instead calling Render Win, and what we get as a result of that

  • is a screen that says, you win, and none of the rest of the content of the page

  • is there anymore because we're not calling the Render Problem

  • function, which is the function that's ultimately

  • going to be displaying the problem and the input field and the score field.

  • It's just going to display you win.

  • COLTON OGDEN: Some virtual fanfare.

  • BRIAN YU: Yeah, virtual fanfare.

  • You know, we could style it up a little bit.

  • We go up here and say, all right, for the winner, let's go ahead

  • and change the font size to 72 pixels.

  • Let's go ahead and change the color to be green.

  • And then we could try winning again.

  • For the sake of time, I'm going to say when I get three questions right,

  • we win the game.

  • So 2, 15, get the third question right, and all right, you

  • win shows up in green in big text, and so that's something

  • that you can do there as well.

  • COLTON OGDEN: Nice.

  • BRIAN YU: All right, so there we have it.

  • There is actually a complete React web application

  • that just exists inside of an HTML file now

  • that allows for maintaining a state that dynamically updates itself

  • based upon that state, and so hopefully that gave you a good sense for React.

  • We still have some time left, though, so happy to answer questions

  • if there are particular questions about aspects or features of React,

  • or if we want to make particular extensions

  • to this particular application, certainly something we

  • could do there as well.

  • COLTON OGDEN: Yeah, that was an excellent talk.

  • Thank you so much for coming on the stream today.

  • BRIAN YU: Yeah, of course.

  • COLTON OGDEN: But yeah, we'll stick around for a few minutes.

  • So if you have any questions, let us know, and yeah.

  • That was React, flashcards.

  • Feels nice building something tangible that people can at the end of the day

  • look at and experiment with, because we're

  • talking in sort of abstract terms, a lot of frameworks,

  • but it's nice to actually see it be sort of put

  • to the grindstone for an actual use case.

  • BRIAN YU: Definitely.

  • One last thing I'll show, actually, since we have a little bit of time.

  • One nice thing about React that we haven't even seen yet

  • so far is nesting components within each other, which

  • I mentioned at the very beginning, but we didn't actually

  • get a chance to see them.

  • So maybe this You Won component, that right now is actually

  • a pretty simple one that just says you won, for example, we

  • might want to separate that out into a different component,

  • for instance, just like a winner component that gets

  • displayed anytime you win something.

  • You might imagine that if this application were extended

  • to have a whole bunch of different games that

  • are part of this, that you might have the winner screen appear on all

  • those different games once you win it, and we

  • might want to factor that out into a different component, for example.

  • And so we could do that pretty easily, by instead of just defining a class

  • called App, let's also define a class called Winner

  • that also extends react.component.

  • And this defines a render function that's

  • just going to return a div whose ID is winner, that says you win.

  • Same as before, but we've just separate out into this winner component.

  • And down here, in Render Win, rather than returning this div,

  • I can just say Return Winner, return that Winner component,

  • and let me set the game winning score to be three just

  • to make this a little easier again.

  • And assuming we did everything right here, if I refresh the game,

  • you get some questions right, get the last question right,

  • we still get the same you win that shows up.

  • But this time rather than just being part of the same app component,

  • it's part of a separate component, and so this Winner component

  • might be something that other games could use as well.

  • Now you might imagine that maybe we want this Winter component to be customized,

  • for instance, that doesn't just always say you win,

  • but says you win, like, the addition game,

  • for instance, where we have the name of the game as part of the winner

  • component.

  • Now of course, the name of the game is going to vary depending upon the game,

  • so different games might try to render the Winner component in different ways.

  • And so what am I do in this case is to say, you win, and what I want to do

  • is not just render a Winner component, but pass some information

  • into the Winner component, pass information

  • the same way you might pass arguments to a function, for instance.

  • We're going to pass what are called props

  • to this component where I'm going to say maybe the name of the game.

  • Const name is the addition game.

  • And I'm going to say, all right, winner, let's pass in a variable called

  • name that is equal to this JavaScript value,

  • again using the curly braces to mean insert a JavaScript variable here,

  • that is called Name.

  • So this is something we haven't seen before.

  • This is an example of a React prop, a property of the Winner component

  • that I want to pass into the Winner component such that it can use it.

  • And these props, unlike the state, which can change and can update,

  • the props are never going to change.

  • You pass in the name into the Winner component,

  • and the Winner component is never going to change its own props.

  • COLTON OGDEN: It's like in an image tag, having like, source equals

  • [INTERPOSING VOICES]

  • BRIAN YU: Yeah.

  • COLTON OGDEN: Actual app.

  • BRIAN YU: Yeah, exactly.

  • It's very similar to an HTML attribute, the way

  • you would add a source for an image tag or an href for a link tag,

  • for instance.

  • That's the same idea.

  • And so now here in Winner, rather than just saying

  • you win, I can say you win this.props.name, meaning take the props

  • and extract the name from them and display it

  • there such that now if I play the game, oh I've got 1 plus 1 for a second time,

  • 1 plus 6, get that right, you win the addition game, right.

  • We've been able to shrink that down so you can see it a little bit better.

  • COLTON OGDEN: I have the chat in the way a little bit there.

  • BRIAN YU: No worries.

  • And so that's allowed us ultimately to customize this Winner component even

  • when using it from an outside component by passing in some prop, the addition

  • game, into the Winner component such that it can display and render

  • correctly.

  • You might imagine that other games that are also using the same Winner

  • component could use the same component but pass different props into it as

  • well.

  • COLTON OGDEN: Makes everything super nice and modular.

  • M Kloppenberg says, thanks, Brian.

  • Clear as always.

  • Enjoyed your CS50's wen explanations as well.

  • BRIAN YU: Great.

  • Glad to hear it.

  • Glad you enjoyed it.

  • COLTON OGDEN: Can you write an app for the typing test, says [INAUDIBLE]..

  • Probably not today, but maybe in the future.

  • That would be a cool idea, actually.

  • BRIAN YU: Not today, but certainly something

  • you could do with the knowledge that you have with React right now.

  • It would really be probably some state.

  • Maybe that state is going to contain information

  • about what it is the user's expected to type,

  • and state about what the user has actually typed.

  • It might contain state about what time they started typing, for instance,

  • and then based on the current time, the time they started typing,

  • and the number of characters they've typed,

  • you could probably estimate a rate at which they were typing,

  • and maybe you have some algorithm for factoring in mistakes they make

  • or errors they make there as well.

  • So definitely something that you could do using the same general paradigm.

  • COLTON OGDEN: France P asks, any thoughts on the new React feature

  • hooks?

  • BRIAN YU: New React feature hooks.

  • Actually not too familiar with those feature hooks, but happy to chat

  • more about that later afterwards.

  • If you want to shoot me an email or some instance,

  • I'm happy to chat about that too.

  • COLTON OGDEN: Do you want to maybe read off Cloud's question after that?

  • BRIAN YU: When you added the second app in,

  • could you create a multiplayer kind of interface

  • that compares scores at the end of both player's completion

  • and displays the overall winner?

  • Would increasing difficulty be as easier as easy

  • as increasing the multiplied random number

  • each time you get a correct answer?

  • Yeah, certainly.

  • So two separate questions there, one about the multiplayer game.

  • So for those who have joined a little bit late,

  • one thing we did at the beginning of this

  • was to say, all right, what if we, instead

  • of just rendering the application once, tried rendering the application twice.

  • So I have the application twice here inside of the same div,

  • and then I rendered the game here such that I now have

  • two parallel games that are going on.

  • Certainly you could imagine that we had an interface that compare scores

  • at the end of it and tells you who was the overall winner.

  • But in order to do that, you probably would

  • need to have some other component, some wrapping component that

  • wraps the two games, and that contains its own state of keeping track of like,

  • who is winning the game, that handles events for when an application wins

  • a game, for instance.

  • So definitely something you could do.

  • It would just require probably an additional component

  • to keep track of managing all those different games.

  • COLTON OGDEN: Like a game manager, and then those two are app manager,

  • and then have those two apps.

  • BRIAN YU: Yeah, yeah.

  • Exactly.

  • Would increasing the difficulty be as easy as increasing

  • the multiplied random number each time you get a correct answer?

  • Yes, exactly, and in fact, we could do that right now

  • without a whole lot of difficulty.

  • Rather than just adding numbers from--

  • let's try and find it.

  • This will get us numbers from 1 to 10.

  • If we want to make the game more difficult, actually,

  • why don't we try taking a number from 1 to 10

  • and adding state.score to it, for instance?

  • So this will update the random number, adding whatever the current score is,

  • such that as my score gets higher, the numbers

  • that are inputted get more difficult. And let's go ahead

  • and change the winning threshold to 10 just so we can get some more

  • opportunity to try questions.

  • But now all right, 2, 11, yep, 15, 17, and all right.

  • So now, 12 plus 12, this is not a problem

  • that we would have gotten before if we were just going from a 1 to 10 scale,

  • but because we're now increasing the values of the numbers

  • that we're typing in, every time we do it,

  • we're going to start seeing higher and higher numbers.

  • And if we do it a couple more times, like 15 plus 14,

  • these are the types of numbers that we weren't getting in the original game.

  • But by increasing the number, you could definitely

  • make the game a little bit more exciting.

  • COLTON OGDEN: Thanks, Brian.

  • You explained very well everything.

  • You did a good job, awesome job.

  • Boston Mass says, wait, you're in Mass?

  • So yeah, we're in Cambridge, Massachusetts,

  • where Harvard University is located, shooting here live from campus,

  • actually.

  • Every time there is a long message, Colton makes the other person read it.

  • That's actually true.

  • That's a good point.

  • I thought that was Zac Efron.

  • Brian, could you make another session showing the multiplayer interface?

  • BRIAN YU: We haven't scheduled the remainder of sessions yet,

  • but certainly I would encourage you to try making the multiplayer interface

  • if that's something that's interesting to you.

  • You can do it using much of the same technologies and features

  • that we talked about today, and this idea of just composing components.

  • In the same way that we put a Winner component inside of our app component,

  • you might have a game manager component inside

  • of which are two apps, for instance, and you could give that a try certainly.

  • That's Something to work on.

  • COLTON OGDEN: Why don't you go ahead and read

  • the long message towards the bottom?

  • BRIAN YU: Would adding a restart button essentially just

  • be adding a button that instantiates a fresh copy of the React component

  • on click?

  • You could do that.

  • You could instantiate a fresh component of the react component,

  • though what might be easier would just be resetting the state back

  • to the original state.

  • So in fact, let's try that, why not.

  • It won't be too difficult.

  • So after the end of the score, let's add a button,

  • and that button is going to be reset.

  • So now we've refreshed the game.

  • Here is the reset button.

  • I got some questions right, but of course,

  • clicking the reset button right now does nothing.

  • So let me add something to this button.

  • On click, let's call a function called this.resetgame.

  • Now of course, I haven't defined Reset Game yet, so let's define it now.

  • Let me go down here to the bottom.

  • Let's do resetgame is going to be a function that takes in the event,

  • although actually, I don't think we're going to need the event.

  • We're going to set the state.

  • And all right, what things do we need to reset?

  • Well, Num1, let's set it back to 1, just for the beginning.

  • Num2, we'll set that back to 1.

  • The response we'll set back to the empty string.

  • Whether or not you've got the answer incorrect, we'll set that back to false

  • so it goes back.

  • The score, we'll set back to zero.

  • This is the original state of the application,

  • and when we reset the game, we're just going to reset the state back

  • to the original state, and maybe you can imagine factoring this out

  • to avoid duplication.

  • For now, this will suffice for our purposes, such

  • that now, I'm playing the game.

  • I get some questions right.

  • Whoops, that was wrong.

  • 16 I type in.

  • I get a wrong answer, for instance.

  • All right, my score is three.

  • I'm not too sure about this question.

  • The answer is wrong, so the text is red.

  • But I click the Reset button, and all right, the game resets back to normal.

  • The state went back to normal.

  • Num1 and Num2 go back.

  • The answer's blank again.

  • The score goes back to 0.

  • And so you can generate that effect of resetting something

  • just by taking the state and setting it back to normal.

  • COLTON OGDEN: Nice.

  • It's like an encore.

  • Cool, all right.

  • Well, it's 3:58.

  • We'll stick around for a couple more questions, but tune in on Friday.

  • On Friday, we're actually going to be doing some Unity programming in C#,

  • so a completely different venture than today.

  • Oh, Cloud also follows up with his other question that I made you read.

  • It says, thank you for answering.

  • I'm in second year of software engineering.

  • Busy with Swift at the moment.

  • First time encountering your live feed, and really awesome, so thanks.

  • Or we can define original state function,

  • and just use that function to call.

  • More modular, less dry.

  • BRIAN YU: Yeah, exactly.

  • So I mentioned before that I was doing a bit of duplication of code

  • here, where in the reset game, the state I

  • was setting it to was equivalent to the state

  • that I was originally setting the stop state to.

  • So you could imagine either putting it inside of some sort of class variable

  • that everything has access to, or by using a function,

  • for instance, that you could try to avoid that need for that redundancy,

  • for instance.

  • COLTON OGDEN: Is your computer equipped to do GitHub on this account?

  • Would you be able to fire up a link for it so it's in the video,

  • or do you want to wait to do that later?

  • BRIAN YU: Let's go ahead and do that later.

  • COLTON OGDEN: OK, sure thing.

  • Yeah, because Bavick Just said, you're going to put this on GitHub, right.

  • Please share the link.

  • We'll share the link, so it's going to go up on YouTube,

  • and it'll be in the description.

  • We'll post the GitHub link in the description there.

  • We're going to stick around for just a couple more minutes,

  • but we hit an hour and a half, which that's the David time, as well.

  • BRIAN YU: Is it?

  • An hour and a half?

  • All right.

  • COLTON OGDEN: It's a good amount of time.

  • But yeah, that's a nice example.

  • It kind of introduces all the core concepts very nicely.

  • BRIAN YU: Yeah.

  • Thanks, everyone, for listening.

  • Hope you enjoyed.

  • Hope you learned a little bit more about React

  • and how it can be useful, as opposed to just using plain old JavaScript,

  • which you could design an application like this just using JavaScript.

  • Certainly react is not necessary to do something like it.

  • But especially as web applications get more complicated

  • and web interfaces get more involved in the front end, and what's going on,

  • and there's a lot of things happening and a lot of things changing

  • inside of the application, React can just be very, very powerful

  • for trying to minimize the amount of code you have to write

  • and maximizing the expressiveness of the work that you're doing.

  • Again, I'm Brian.

  • COLTON OGDEN: Colton Ogden.

  • So Brian, you head teaching fellow for CS50.

  • What class are you?

  • BRIAN YU: I am currently a senior at the college.

  • COLTON OGDEN: So the 19?

  • BRIAN YU: Class of 2019.

  • COLTON OGDEN: Class of 2019.

  • And I am Colton Ogden, technologist here at Harvard University.

  • And we do this stream so far pretty consistently four times a week-ish.

  • So again, we'll be doing another stream on Friday.

  • Students or teachers?

  • Well, you're both.

  • Brian taught the CS50 web class.

  • I'll put the link in the chat one more time so they're here.

  • So Brian taught cs50.edx.org/web, which was not a React course,

  • but like you said earlier, much more of a back end oriented, Flask, Django,

  • that sort of thing, cyber security and excellent GitHub first lecture too,

  • if you want to review some GitHub fundamentals.

  • And then I am not a student here, but I am a full time technologist

  • and also do a little bit of teaching and other stuff.

  • And I taught a games course.

  • So you can go to both those links.

  • Those are both of our courses from this year on edX.

  • So awesome.

  • [INAUDIBLE] says this was great.

  • Thank you both.

  • Have a great day.

  • Thanks so much, [INAUDIBLE].

  • Thanks for coming by again.

  • And thanks so much, everybody else.

  • We'll go to the wide shot here where we still

  • see the chat on the left hand side.

  • So this was Brian Yu with an intro to React.

  • Stay tuned for Friday, but this is CS50 on Twitch.

  • Anything you'd like to follow up with?

  • BRIAN YU: Yeah, thanks so much.

  • Enjoy the rest of your day.

  • COLTON OGDEN: Awesome.

  • Thanks so much.

COLTON OGDEN: All right.

字幕與單字

單字即點即查 點擊單字可以查詢單字解釋

A2 初級

REACT BASICS - CS50 on Twitch, EP.8 (REACT BASICS - CS50 on Twitch, EP. 8)

  • 2 0
    林宜悉 發佈於 2021 年 01 月 14 日
影片單字