‫Let's now look
‫at the super important useState hook again
‫and review some important details
‫that we have already talked about as well.
‫So we have been using the useState hook
‫since almost the beginning of the course
‫because this is in fact the most important hook in React.
‫So we have used it in many different ways
‫and we know pretty much how it works at this point.
‫However, I want to again, review some important parts of it
‫and I want to draw your attention
‫to one very important detail, which is the fact
‫that these initial values that we pass into useState
‫only really matter on the initial render.
‫So let's see an example of that and let's say,
‫that we actually wanted something like this here to work.
‫So we wanted a piece of state called isTop
‫which is true if the imdbRating is greater than eight.
‫Now, we cannot do this as we already learned
‫in the previous lecture, but we might think that this works.
‫So basically doing this, so imdp greater than eight.
‫So let's see if that works actually.
‫And let's then log this state to the console.
‫Okay.
‫Let's search for a movie, as always,
‫and then let's wait for it.
‫And we see that this log here coming from line 266
‫which is this one here, is indeed false
‫even though the rating here is actually greater than eight.
‫And if we take a look at our list of hooks
‫then we also see that this one is set to false.
‫So why is that?
‫Well, it is because of the reason
‫that I just mentioned before
‫which is the fact that whatever we pass into useState
‫is the initial state.
‫And React will only look at this initial state
‫on the initial render.
‫So when the component first mounts.
‫However, when the component first mounts here
‫the IMDB rating will still be undefined.
‫And so this year is then false.
‫And so it will stay false forever
‫because nowhere we update the state
‫and on the second render,
‫so when we then finally get the movie data,
‫this will not be executed again.
‫And so therefore, again, it will stay false forever.
‫Now, one way of fixing this would be to use a useEffect.
‫So if we did useEffect passing in a function
‫and then we wanted to run this effect
‫each time that the IMDB rating updates.
‫And so each time that does happen
‫then we want to call setIsTop
‫and then we can do imdbRating greater than eight.
‫And so in this case, this should then work.
‫And let's see. And indeed now it is true.
‫And if we take a look again here at our...
‫Yeah, at our different hooks,
‫we see that now indeed isTop is true.
‫So our fourth hook here.
‫And so that is simply because of this useEffect.
‫Now of course, in this situation
‫we shouldn't even use a piece of state in the first place.
‫So if this here was the functionality that we really wanted
‫then what we should do is derived state.
‫So we shouldn't create a real state with the useState hook
‫but instead we should just do const isTop
‫and then simply imdbRating greater than eight.
‫So let's comment all of this here out, give it a save.
‫And if we then log that again to the console
‫you see that this simple code works seamlessly.
‫So let's wait for a here.
‫Cleaning our console. And so it is true.
‫And so that's because this variable here
‫is of course, regenerated
‫each time that the function here is executed.
‫So after each render.
‫And so this is the power
‫and one of the great advantages of derived state,
‫which is that it updates
‫basically as the component gets re-rendered.
‫And this is really as simple as it can get, right?
‫So this is pretty important to understand
‫so that the initial state value here
‫is only been looked at by React in the very beginning.
‫So only on component mount.
‫So never forget that.
‫And now I want to come back to this function right here
‫to give you yet another example
‫or another proof that updating state really is asynchronous
‫and that we need to use a colic function to update state
‫in certain situations.
‫So let's say that when we add a new movie
‫to our watch list right here
‫we want it to display the average of the rating that we gave
‫and the rating that is coming from IMDB.
‫So we want that to be displayed right here
‫instead of closing the movie immediately.
‫So let's first of all here remove this part
‫and then let's create a new piece of state.
‫Because if we want to display something on the screen,
‫well, then we need a new piece of state.
‫So let's call this avgRating and setAvgRating.
‫And useState, and let's just set it to zero.
‫And then we want to render that here.
‫Really somewhere, it doesn't really matter
‫because we will remove this here in a minute anyway.
‫So this is just to give you another demonstration
‫of updating state asynchronously.
‫So where is that function? Here it is.
‫Okay, and so now here we should see the zero.
‫And I used the value of zero here
‫and not the current IMDB rating because again,
‫this will just be undefined in the beginning.
‫And so there's no need to place that there. All right?
‫But then as we click on this button here
‫then this function here is executed.
‫And so let's then actually set that state.
‫So setAvgRating, and let's say
‫that first we wanted to set it
‫to the actual current IMDB rating, which is a string.
‫So let's convert that to a number. So IMDB rating.
‫And now watch what happens if we log this to the console
‫or maybe even if we alert this.
‫So then it becomes really visible.
‫So avgRating.
‫So let's see.
‫And so the avgRating should now be 8.6
‫because we set it to IMDB rating, which is 8.6.
‫So watch what happens. Well, it is still zero.
‫And so that's again,
‫because the state is set asynchronously here.
‫Or in other words, we do not get access to the updated state
‫right after doing that.
‫So right after we call the state updating function.
‫So only once React is done processing this event handler
‫it will then update all the state and re-render the UI.
‫All right. But anyway, let's now do another one.
‫So setAvgRating.
‫And so let's now attempt to calculate the average.
‫So taking imdbRating.
‫Or actually we want the avgRating.
‫So avgRating plus the userRating and then divided by two.
‫So let's see, let's delete this here.
‫And let's use 10 this time.
‫And then we get a wrong average here.
‫So our average is not correctly being calculated.
‫So this five here is really just 10 divided by two.
‫So the reason for that is that here
‫the avgRating is still at zero.
‫And so then zero plus 10 divided by two is indeed the five.
‫But why is the avgRating still at zero here
‫even though we have updated it before?
‫And by now you already know the answer.
‫So it's asynchronous state setting,
‫which means that at this point here
‫the avgRating has not been set yet.
‫So it's still at zero,
‫which is the initial value right here.
‫And so because of that,
‫we say that the avgRating state is stale at this point.
‫So we have stale state right here.
‫But luckily for us, we already know how to solve this,
‫which is by passing in a callback function.
‫And so that callback will get access to the current value.
‫And so let's again call that avgRating,
‫but of course, it could be called anything.
‫So let's try one more time.
‫Again 10. And beautiful.
‫So now we get the correct average. Nice.
‫So this time what happened
‫was that the average was again set to the imdbRating,
‫so the 8.6, but then in the next line here
‫we already got access to that new value.
‫And then here the 8.6 plus the 10
‫gave us the correct, the average.
‫And again here, this could be really called anything
‫and it would always work in the exact same way.
‫So if we do that again, then yeah, we will still get 9.3.
‫And so that's because this is simply the name
‫of the argument of the callback function
‫that React will pass into the function.
‫So it will simply pass the current state value
‫into the function.
‫But we can then of course give it any name that we want.
‫But let's put it back.
‫And indeed, let's actually remove all of this
‫that we just wrote.
‫So this was just yet another experiment
‫but I hope that it was a helpful one.
‫So here...
‫Actually no, I thought I saw some error there.
‫So let's put it back.
‫And so now the application should work just like before.
‫All right, and now there's just one final thing to learn
‫about the useState hook,
‫which is that besides using a callback like this
‫to update state, we can also use a callback
‫to initialize state.
‫And so let's learn how to do that in the next lecture.