字幕列表 影片播放
-
[PIANO PLAYING]
-
SPEAKER: OK, let's get started.
-
Welcome back, everyone, to CS50 Beyond.
-
Our goal for today--
-
this is the second-to-last day of the course.
-
And goal for today is going to be to pick up really
-
where we left off yesterday.
-
So yesterday we introduced a new JavaScript library called React.
-
And React was designed to make it easier for us to build
-
interactive and dynamic web pages.
-
And we did so by creating components and ultimately via declarative programming,
-
where we were describing what it is that the page should look like,
-
whether certain variables should belong in certain places on the page,
-
whether we should be iterating over a particular variable in order
-
to display a list of things on the page.
-
And then the only thing we needed to do in order to edit the page was
-
rather than go into the dom and manipulate the dom and say,
-
update this element or update that element, we would just say,
-
change the data.
-
Set the state of the component to be something different.
-
And the page would automatically render and re-update
-
the parts of the page that needed to in order to reflect those changes.
-
And so the goal of today is to continue along those lines and in particular,
-
emphasize thinking in React, thinking about how
-
it is that we take an application that we're going for,
-
decompose it into pieces, and then try and put it back together, such
-
that we can figure out what components, what state we
-
need to keep track of in order to make our applications
-
interactive and useful.
-
Along the way we'll talk about things like React lifecycle
-
and about how to get your React applications, which
-
are front-end applications, to interact with the back end, like a server,
-
for instance, connecting to APIs then.
-
And then we'll have some opportunity for hands-on projects, as before.
-
And so we'll start by taking a look at an example from yesterday
-
and begin to answer some of the questions
-
that yesterday I pushed off until today.
-
And so we'll take a look at counter.html And counter.html,
-
you'll recall from yesterday, was just an application
-
whereby it displayed a number that defaulted to the number 0.
-
And then we had increment and decrement buttons, or plus and minus buttons,
-
where all those buttons' data will change the value of the number.
-
We started with 0.
-
We can go 1, 2, 3, 4, 5 by clicking the Increment button plus the Minus button
-
in order to go back down.
-
And ultimately the way that we implemented
-
that program was to say inside of counter.html,
-
we had some state inside of our counter component
-
that initially was just set to the number 0.
-
And then when we click the On-click button for the plus or minus buttons,
-
we would call the increment or decrement functions.
-
And all those increment and decrement functions would do
-
is call the this.setState method, which is a special method in React that
-
takes the state and updates it, in particular by taking the count
-
and setting it to whatever the count minus 1 is in the case of decrement,
-
and in the case of increment, taking the count and adding 1 to it.
-
Of course, this state only exists when this component
-
is loaded onto the screen.
-
And as soon as we close the page and reopen it,
-
we're getting a brand-fresh, new component.
-
It's remount onto the screen.
-
And as a result, if I increase the number to, say, 5, for example,
-
close the page, and then reopen the counter.html, we're back to 0, right?
-
We reloaded the page.
-
The JavaScript is rerun.
-
And as a result, our state is reset back to the initial state
-
as defined by the constructor, which, in this case, is the number 0.
-
Now, before we got to the world of React and we were just
-
dealing with plain JavaScript, how do we solve this problem,
-
if we wanted the state to persist between when you open the page,
-
closed the page, open it again?
-
We cached it in a place called local storage,
-
a place within the browser, whereby we could
-
say I want to store the state of the application inside of local storage,
-
such that later on in my application I can refer back to local storage
-
and say, get this value out of local storage and put it into my application.
-
And in React, we can do something very similar.
-
Every React component has a number of what are called lifecycle methods,
-
or functions that are going to run at a particular point in the component's
-
life.
-
And one of the most common is a special function
-
in React called componentDidMount.
-
There are a number of others.
-
The only one we're going to talk about today is componentDidMount
-
And componentDidMount is a special method in React
-
that is going to run as soon as a component is mounted into the dom.
-
In other words, as soon as we add this component into the dom,
-
this is the method that's going to run before it actually ultimately renders
-
the contents of what's going to show up.
-
So any work we want to do of, like, setting up the component,
-
we can do inside of componentDidMount.
-
And so one thing we can do, for example, is get something out of local storage.
-
I can say, local storage.getItem count in order
-
to say, all right, let me get the count value out of local storage.
-
And I'll save that inside of a variable that I'm just going to call count.
-
So if there was an item called count in local storage,
-
I'm going to extract it from local storage
-
and save it inside of a variable called count.
-
Now, there's a chance that there was no count item in local storage,
-
that this is not equal to any particular value.
-
And so it's possible that count is going to be equal to null.
-
So let me just do a check.
-
Let me check if count is not equal to null,
-
meaning there actually was some count saved inside of local storage,
-
well, then what I'm going to do is I'm going
-
to call this.setState, setting the count equal to the result of parse int count.
-
It's going to be stored as a string so we'll parse it as an integer
-
in order to update the state of the application.
-
So componentDidMount, if you think about the chronology of things,
-
is going to happen after we've constructed this component
-
and inserted it into the dom.
-
And we want some initial code to be running
-
at the beginning of this component's life,
-
whereby we're saying from local storage, let's extract the counter variable.
-
And as long as it's not null, then go ahead and update the state,
-
setting count equal to the result of parsing
-
the int of whatever the value of the count variable is.
-
So now we have a component that can read from local storage
-
and update its initial state based on that information.
-
What's the missing half of this now?
-
Yeah?
-
AUDIENCE: [INAUDIBLE] isn't count equal to count?
-
Why [INAUDIBLE]?
-
SPEAKER: So the way local storage is going
-
to store things is it's going to store the values of strings.
-
And so that's the way that most browsers choose to implement local storage.
-
And so when we read them from local storage,
-
we have to assume that what's coming into us will be strings.
-
And so we can parse them into integers in order to be able to use them.
-
So we've got saving things-- or retrieving things from local storage.
-
And now that I just gave away the missing piece of this
-
is saving things into local storage, whereby we're getting the item count,
-
but we're never setting the item count.
-
And so we want this to happen before the window goes away.
-
If ever I try to close the window, we want something to happen there.
-
And so we'd like to add some sort of event listener
-
for when I try to close the window, for example.
-
And oftentimes you might see other web applications
-
that have implemented something similar, whereby
-
if you try to exit out of a web document before saving,
-
you might get a warning message that says,
-
are you sure you want to leave this page without saving your changes,
-
for example.
-
Or you haven't completed this action.
-
Are you sure you want to do this thing?
-
And so just in the same way that we were able to add event listeners to when
-
the dom is done loading or when you click on a button,
-
we can also add an event listener to the window
-
to say, like, before this window's contents are unloaded,
-
let's run some particular code.
-
And so to do that, I'll say window.addEventListener.
-
And the name of this event that we're going to be using
-
is a special event called before unload.
-
In other words, before this window's contents are unloaded,
-
let's run some code.
-
Before we get rid of this component, let's run a function.
-
And that function is going to say local storage.setItem.
-
And then setItem, again, takes two arguments.
-
The first is the key, the name of the thing that we're setting.
-
And the second is the value, what value it should take on.
-
The key, as with line 22, we got the item with key count.
-
So we should be setting the item with key count.
-
And what is the value?
-
What should we be setting count equal to?
-
Yeah?
-
AUDIENCE: This.state.count?
-
SPEAKER: This.state.count, perfect.
-
We want to set count equal to whatever the current value of count
-
is inside of this component state.
-
To get to this component state, we can say
-
this.state to get at the state of the component
-
and then dot count it to say, all right, let's go into the state,
-
extract the thing with the key count, and use that as the value
-
that we save into local storage.
-
And so assuming I didn't make any mistakes here,
-
if I go back to the page, refresh the page,
-
I can increment the counter 1, 2, 3, 4, 5.
-
And now if I close the counter, that's going
-
to trigger the window.beforeUnload event, which
-
is going to save the number 5 into local storage.
-
And if I open counter.html again, press Return, all right, great,
-
the component now shows me the number 5.
-
It's been able to save that state inside of local storage,
-
such that even when I closed the page and open it back up again,
-
I've been able to maintain the state of the application.
-
Yeah?
-
AUDIENCE: [INAUDIBLE]
-
SPEAKER: For refreshing the page as well?
-
Yeah, if you refresh the page, if I go to 10, for example, and click Refresh,
-
it stays at 10 because before the contents of the page
-
are unloaded before the refresh, it's going to trigger that event listener.
-
Yeah?
-
AUDIENCE: Are the items that are kept in local storage--
-
like say you want [INAUDIBLE] the program [INAUDIBLE]..
-
Are the items in local storage, are they secure from--
-
if someone hacked into your code, broke in, could they get into it?
-
SPEAKER: The items inside of local storage
-
are actually quite accessible to anyone.
-
So anyone who could get access to the browser could get access to it,
-
insofar as all I need to do is go into inspect, and I can go into, I think,
-
it's application, at least in Chrome, and go to local storage.
-
And over here I see a count and also a counter from a previous time
-
that I was doing an application with local storage.
-
So these values are highly accessible.
-
And you can edit them as well.
-
And so probably best not to store anything super secure inside
-
of local storage for that reason.
-
You'll probably want to store things on the server side.
-
And we'll talk about interaction with server side in just a moment.
-
Yeah?
-
AUDIENCE: Will you let me know the website [INAUDIBLE]
-
variables that you put in local storage [INAUDIBLE]??
-
SPEAKER: Local storage is domain specific.
-
So if you have domain1.com, and you're storing things inside of local storage,
-
domain2.com is going to have access to a different local storage.
-
And so those are kept separate.
-
AUDIENCE: Is there a way to make it so local pages use the same [INAUDIBLE]??
-
SPEAKER: So, yeah, if they're within the same domain,
-
they can use the same local storage.
-
For example, if I were to create another file--
-
and I'll just demonstrate.
-
Like, if I just copy counter.html and call it, like, newcounter.html,
-
which is a different file, and I open up newcounter.html,
-
it's still going to have access to that same local storage.
-
It still has access to the number 10.
-
So it can draw up on those same values.
-
Other things?
-
Yeah?
-
AUDIENCE: Can you just explain a little bit more of the difference
-
between componentDidMount and why do we need didMount [INAUDIBLE]??
-
SPEAKER: Yeah.
-
So componentDidMount, there are a number of what
-
are called lifecycle methods in React, which are canonical places where you
-
can put code, and you can guarantee that React
-
will call upon those functions at particular times.
-
And so in fact, so componentDidMount is one of them.
-
ComponentWillUnmount is another one of them
-
that React offers, which is sort of the inverse of that,
-
which is when we're about to remove information from the dom.
-
There's even a componentWillUpdate for whenever
-
a component is going to refresh itself and change something