So to make sure that the computer can actually finish that game and guess the right number,
we need to check what the computer guessed and then kind of end the game
if it's the number we entered. For that, we can use another React hook and that's the useEffect hook.
useEffect allows you to run side effects or in general, allows you to run logic after every render cycle
and just as mentioned before, if this whole React hooks thing is relatively new for you, definitely check
out some dedicated React hooks resources or dive into my React Complete Guide Course where I cover hooks
in detail. So what I'll do with useEffect now is I'll call it here
after initializing my state and my refs here and in there, we've has a function, so useEffect takes
a function and this function by default runs after every render cycle for this component. So every time
it has been rendered, this function is executed, after it has been rendered, that's also important,
not before, not simultaneously, after.
Now in there, I want to check if the current guess computer made is equal to the user choice because
that means the game is over.
Now that can't be the case for the first render cycle of course because we exclude the user choice from
the guessable numbers but from the second row on,
so once we clicked lower or greater for the first time, that can happen.
So in there, I then want to kind of fire a
the game is over message and send that to app.js so that we can swap the game screen for a game over
screen.
Now we don't have that screen yet, so let's add it,
let's add a game over screen here in the screens folder and let's create a very simple one for now, we'll
fine tune it later. In there,
I'll simply have a view and a text and a stylesheet,
so what we typically import from React Native and then have the game over screen component in there which
take some props and then return some jsx in the end.
Here we have these styles with Stylesheet.create and then we export the game over screen as a default.
Now in there as I said, I want to keep this simple for now, I'll just have a view in there with a text
of the game is over and we'll output more details there later. For now,
here I'll just assign some style, my screen style which I'll add to this object we passed to the style
sheet
here at the bottom, set flex to 1 and maybe justifyContent to center and then align items to center,
so that this text is centered for the moment.
Now we have the game over screen and we want to render this instead of the game screen
if the game is over. So let's go back to the app.js file and import the game over screen from
the screens folder and there from game over screen
and the question now of course is, what's our condition for rendering this? Well in the end, we'll need
one additional piece of information anyways
and that's the number of rounds it took the computer to finish the game.
So one thing I want to store here in the app component is another state
I manage and that is the number of rounds it took to finish which is zero initially because
we haven't started the game yet
and I'll name this guess rounds and set guess rounds and you can name this whatever you want.
Now the goal is to set this when the game is over.
So for that, I'll also add another function here to the app component,
game over handler and there, I want to get my number of rounds as an argument, so I expect to get this
here so that I can call set guess rounds to my number of rounds
I got here. Now the game over handler should be triggered from inside the game screen obviously.
So here on the game screen, I want to pass in a prop which I'll name onGameOver,
sounds like a fitting name which can be called from inside the game screen then or which holds a function
reference which can then be called from inside the game screen and the function reference is a reference
at this game over handler function of course.
So inside of game screen, we can now use the onGameOver prop to execute this function and pass the
number of rounds it took the computer to guess our number,
then we set this number of rounds here, store it in our guess rounds state and now in the app component,
we know that if guess rounds is zero, the game hasn't started yet or it's running, if it's greater than
zero, then the game over handler executed
and the game is over.
So we want to show the game over screen
if guess rounds is greater than zero.
By the way if we start a new game, I also want to reset my guess rounds to zero because if a new game
starts,
we want to reset the number of rounds the computer took to 0.
So if it's greater than zero, the game is over,
so in that case, I want to show the game over screen.
So here if I check if we have a user number, in which case I show the game screen, that's only correct
if guess rounds is smaller or equal than zero,
smaller is not possible but still, we can check for that.
So if that's the case, then we know the game is certainly running,
else if guess rounds is greater than zero, then we know the game is over and therefore content will be
equal to game over screen, right now
that's just a component like this without any props which we pass in.
So now we have a condition where we render the game over screen, all we now need to do, we need to use
the onGameOver Prop here in our game screen to in the end call this function and forward the number
of rounds to the app component.
So back in the game screen, if useEffect here determines that the right choice was made, the right guess
was made and therefore the game is over, then in here, I want to call props onGameOver as a function
and forward the amount of rounds it took the computer to guess our result or our choice and that's
therefore another state we have to manage here in the game screen. We have our rounds and set rounds and initially,
that is zero, when this component is created for the first time, this is of course zero and rounds is therefore
now what I forward here because that's a number we'll increment with every guess because in the next
guess handler, if we're generating a next guess, besides setting that guess here in our state, I of course
also want to set my rounds and there use the function form where I get my current rounds and I return
current rounds plus one.
So I add one to my current amount of rounds I store in my state, so that the new state is old
rounds plus one because a new round started. So with that, we're managing the amount of rounds and we're
using this as a condition in the app component to render the game over screen and in the game screen,
we check whether the game is over here in useEffect and right now, we do this whenever this component
re-renders.
Now we could do that but we can also simply be more honest or more direct regarding the dependencies
of this effect and that's something you can be or you can do by adding a second argument to useEffect,
first argument is the function it should execute after rendering the component, second argument you passed
to useEffect is an array of dependencies of this function
and here you have to specify any value that's coming from outside of this effect function.
So in our case, that would be the current guess and that would be props user choice and props onGameOver
and whenever such a value changes, this effect will rerun,
wo whenever a task changed after a render cycle, the effect will rerun I should say. If a render cycle
occurred and the values you specified here are still the same
as for the previous render cycle, then the effect will not rerun,
so the effect will now only rerun if one of our dependencies changed. Now as I said, props user choice and
props onGameOver are all the dependencies and to take care of these, I'll use a modern Javascript syntax
where I use object destructuring to destructure my props and get user choice and onGameOver out of
them,
this syntax might look strange but it's like array derestructuring, just for objects, we're pulling these
properties, so these property names out of this props object and store them in constants with equal
names so that here we can now just use user choice and just use onGameOver since we have these values
now stored in constants of that name pulled out of props and I'm doing this because now we can add
user choice and onGameOver as dependencies in this list,
otherwise we would have to add props here and that actually changes whenever the parent component changes
and therefore it's not a good check.
This is a better check because now we make sure if anything else in props changes,
we don't care, only if one of these two values changes, then this effect should rerun. Now with that, we have
our check in place that should hopefully lead to the game over screen being presented if the computer
guessed our numbers, so now let's save this and let's give it a try,
maybe here on Android to mix things up. So I'll enter a number here, 32, confirm, start a game and it's 2,
so it should be greater,
let me also show you how the warning looks like when I'm on Android,
it's this default Android alert. So 32 it was,
so therefore of course it should be greater, should still be greater,
now it should be lower, should be lower, should be greater, should be lower, should be lower, should be greater,
should be greater,
the game is over.
That's looking good, the guess probably was 32, would makes sense regarding the sequence of numbers
we had here and therefore, this output makes sense here.