In this video.
We need to finish working on our answers.
Let's have a look.
As you can see, here we are inside our answer.
And here we don't have any click event.
And actually here we already rendered our answers, but our click here doesn't work at all.
How we can do this.
Obviously we can add here on click event and just use a dispatch.
But as I already said, when we're working with lists, we don't want to write here our context and
subscribe to our store.
This is why we must notify our parent about changes.
So the idea is that answer component simply say, okay, we clicked on the answer and then we can provide
some information to our question.
And then inside question we have here use context so we can dispatch here some change and say, okay,
user clicked on the answer.
So let's do this now for this what we need to do.
We must provide here one more property.
So here we can provide a function so we can say here on select answer and here we are providing function
just like we did with click.
And in this case on select answer is not a property but a function which we are providing from our question.
And here we want to dispatch just like we did previously.
New action and inside we will have type select answer.
In this case we know okay, user selected and answer.
And here is an important part.
Previously we didn't provide any payload inside reducer, but sometimes we need to do this here.
We can provide whatever data we want, but actually the code style is to create here a property payload
and here we might provide some information to say what exactly we clicked.
In our case, we selected an answer, so we might say what answer we selected.
In this case, we can use this information inside our reducer.
This is why here we can say that we are providing inside answer text.
The question is now from where we are getting answer text.
Obviously we could just take this answer local property because this is our string and we can throw
it inside here.
But I want to show you how we can pass some information from our child to the parent.
And in this case, here we have a function and we will call this function on select answer inside our
child answer component.
And this is why here we can provide some information, for example, our answer text.
And now we are saying that, okay, we have an answer component and inside we have on select answer
where we must provide answer text.
Let's use this now.
So we need to jump inside our answer and here we can destructure on selected answer so it comes from
our props.
Now inside we want to write here on div on click event and when click is happening we can just call
here our on select answer and provide inside our answer text.
So this is how our child can give some information to our parent.
Let's check this out.
I'm reloading the page and we are getting the error.
Dispatch is not defined.
Let's check this out.
I'm jumping to our question.
And as you can see here, we used our dispatch, but we didn't write it here.
Just to remind you, when we are using Usereducer and this is what we are returning globally inside
our context, we have two parameters.
First of all, it's state.
Secondly, it is dispatch.
This is why here we are writing this function and it is available locally inside our component.
Let's check this out.
I am clicking here now, but nothing is happening.
Actually it is.
But we don't see this changes because we don't have a console.log inside our quiz context.
For this we can simply write here, console, log reducer and check what we are getting.
So here I'm writing state and action and let's check it once again.
So I'm hitting here on our A and as you can see, here is our reducer.
So we got new action and this is type select answer and here is what we answered.
So here we are getting inside payload some additional information.
Now we need to write one more if for our new action.
But actually we can make it better.
We can rewrite our if conditions with using switch because actually here we always use action type and
it makes sense to make our code more readable.
So here we are writing Switch for action type and inside we need to write our cases and our first case
will be next question.
We already have it.
And now inside I will simply copy everything that we have inside the save and put it inside our case.
Now here we need one more case.
So here we have case for our restart.
And here inside we can simply copy this single line, return initial state and inside switch case condition.
We also need to provide a default.
And here inside default, I want to return our current state without any changes.
Now here I can remove this.
If conditions and return state, we don't need it.
And as you can see here, our code is much easier to read just because we are using switch and we are
writing cases inside.
And now we must create new case for our select answer.
And the question is what we will write here inside.
So actually we need to store inside our state our selected current answer.
In this case, we can highlight the correct answer or incorrect answer by using this information from
our state.
This is why here on the top, inside our initial state, I want to create current answer and by default
it will be simply empty string, which means we didn't select any answer.
Now, here, inside select answer, we can just merge our state.
So here I have spread and here we want to update current answer and we are getting this information
already from action dot payload.
Let's check this out.
I am reloading the page clicking and here what we have inside this state.
As you can see here, we have current answer and here is the text that we selected in this case.
We can compare this text in all our answers and highlight them somehow.
So what I want to do next is fix the problem with our letters.
As you can see here, we everywhere have a and actually we need to render here answers from A to D.
Let's check this out.
If I'm jumping back inside our components answer here, we simply wrote a and this is obviously not
correct what we can do, we can create some mapping by index because actually we always have just four
answers.
And for this we must provide an index inside our answer component.
So we can say here that we want to get any index and now outside we must provide it.
So inside question here, actually, we already provided an index inside key because we need this information
for React.
Now here I want to create additional property index and just provide inside this index.
Now each answer that we have knows its index.
Now here we can create something like letter mapping.
So here I will just name it letter mapping.
And here we have our four letters.
So A, B, C and D, and here we now have an index.
So we simply can use this letter mapping to render it correctly.
So instead of a I will write here letter mapping and here index.
In this case, it will be rendered correctly.
Let's check this out.
And we have correct letters from A to D, Our next step is how we will implement highlighting.
So actually, when I select one answer, I want to highlight the correct answer and incorrect answer,
which we just selected.
If it's not correct.
And then we can hit next question and just continue our quiz and obviously we will see our results at
the end.
So the question is how we will do highlight and actually it is really simple.
We have current answer inside our state, which actually means we must provide in every single answer
our current answer.
And now every answer can compare itself with our current answer.
So let's do this.
Now for this inside question, we must provide one more property current answer and we know this information
from Quiz State dot current answer because we just created it.
Now we can jump inside our answer component and here we are getting our current answer.
But it is not all.
Actually, we already get here.
Current answer, but we didn't get correct answer.
And actually answer by itself doesn't know if it's correct or not.
We can only know it from our question.
This is why we also need to provide this information inside.
So here I want to provide correct answer.
In this case, our answer can highlight itself correctly and we can know it from our current question.
Dot correct answer.
And we have this information directly inside the question.
Let's jump back now inside our answer and the structure here.
Additionally correct answer.
And now we have enough information to highlight our answers properly.
So what I want to do now is create two additional properties for each correct answer and is wrong answer.
So we know if we need to highlight our answer.
So let's create here is correct answer and the question is when our answer will be correct.
First of all, when we have our current answer.
Because if we don't have it, it means that we don't need to highlight anything.
And we need to check here that our answer text, which means our current answer inside is equal to correct
answer, which actually means that our current answer is correct.
The next thing that we need to write is is wrong answer.
And here the logic is a little bit tricky because actually we must apply this wrong red class.
Just when we answered, but we didn't answer correctly.
This is why here we can write that we have a current answer and it equals our.
Answer text, which actually means we clicked and selected exactly this answer.
And we also need to check here that our current answer doesn't equal correct answer.
So we're checking that current answer is not correct.
And these two variables will help us to attach classes here.
But of course, as you understand, we don't want to write here all our logic because it will be unreadable.
This is why I want to create additional properties with classes and then just concatenate them.
This is why here, first of all, I want to create correct answer class and here we can check.
Okay.
If our answer is correct, then we return here.
String correct answer.
And if it's not correct, we are returning here an empty string.
Now we need to do the same for our wrong answer class.
And here we are checking.
Okay.
Is we have a wrong answer.
If yes, then here we will have our class.
Wrong answer.
And if no, here we have our empty string and we need one more class for disabling because actually
we don't want to allow our user to click several times, which means we must disable all our answers
after first click.
So here we can write const, and here we have our disabled class and we can check here that we have
our current answer.
And if we have current answer, this means that we need to disable all our answers.
So here we will have our disabled answer, or in other case it will be empty string.
So we successfully created all these classes and now we can directly merge them inside our class name.
This is why here I will use not a string but brackets.
And now inside brackets we can write some plain JavaScript and here I will create Ecmascript six string
and now inside we can merge several strings.
So first of all we have answer.
We have it always.
Now I have space and here I put correct answer class after this space and here I have wrong answer class
space and here is our disabled class.
And don't forget you need to write it just like normal Ecmascript six string.
Now let's check if it's working.
So I'm reloading the page and as you can see, everything is blue.
Let's clean our console log.
I'm hitting a and first of all, our A is highlighted inside with red and here B is highlighted with
green.
So how it is happening, we clicked on our element and we dispatched our action.
So actually we updated our state and now we have current answer here.
Now inside every single answer we updated information with props about current answer and correct answer.
So these two properties were updated in all our answers.
Now here, every single answer checks itself and checks if it is valid, invalid or nothing was changed.
And if it was changed, this answer was rendered.
So as you can see, we are writing our logic really in declarative way and everything is working out
of the box.
What is more important?
All our answers are disabled after first selection, but here is an important point actually when I
will hit next question.
Our answers are highlighted already because we didn't clean our current answer and it is still filled
inside state from the previous action.
So we must jump back inside our context quiz.
And here we have our next question.
And actually here we must overwrite our current answer and set it to empty string.
In this case, we will always reinitialize this property.
Let's check this out.
I'm reloading the page highlighting something here.
Now next question.
And everything is blue so nothing is highlighted and every next question cleans our current answer.
And the last thing that we are missing in our application is the amount of correct answers.
So actually we doesn't store such property anywhere.
So in our result screen, we can't really render this information.
So let's do this now.
First of all, here, inside state and obviously we want to store this information inside state.
We must create a new property and let's name it, for example, correct answers count and by default
it will be zero.
Now, every single time when we have a correct answer, we must increase this property, which actually
means that we are talking about our case.
Select Answer.
So here we updated current answer.
Now we need to update our correct answer count.
So let's create here additional property.
Correct answer count.
And here we can compare our payload.
So our answer with correct answer of the question.
So here we can write that our action dot payload equals and here we have state dot questions because
we want to take the whole array and here I can use state dot current question index.
So this part will return current question and here I can put dot correct answer.
So when this condition is true, we need to.
Chris, our counter.
This is why here I can put question mark and here we have state correct answer count plus one so we
increase it.
In other case, we don't increase it.
So I will simply return state correct answer count without update.
And now we can simply update this property inside our state.
Now we can use it inside our component.
So let's jump back inside our components quiz.
And here, somewhere on the top, we rendered this information.
So as you can see here, we have this information and here is our property.
So here we have just text.
You've got four of lines of our question answers.
And here we want to write our quiz state dot correct answers count.
And in this case, we will render this information from our state.
Let's check this out.
I will reload the page and answer something because we need to come to the end of our quiz.
So as you can see, here is our result page.
And we got this information from the state.
So you've got two correct answers of eight, which actually means everything is working correctly.
And when we're hitting restart, we are starting again.
And the last thing that I want to do is to clean our state and console.
So actually we just need to remove all console logs from everywhere where we don't need it.
So here is our context.
We don't want this console log reducer, let's reload it again.
So here is one more console log inside quiz context.
Somewhere on the bottom, let's remove it.
And one more was inside components question.
And here on the top we have it.
And also, as you can see, previously we passed information from quiz to question, but we don't need
to use it anymore because now we are using use context and our global state.
Let's reload the page.
And as you can see, we don't have any console logs at all and our application is fully finished.
Now we just need to talk about two important things.
First of all, how to fetch data for our quiz so we can work with API's like in real project.
And secondly, how to deploy our application to production.
And we will do it in our next videos.