In this video, we will render answers for our quiz.
Actually, we already have all necessary information.
As you can see, here I am in our component question and here we have our current question.
And actually we can write here console.log to check what we have in our current question.
And you can see here that we have all our answers.
Let's check this out.
As you can see inside question, we have correct answer, which is a string and incorrect answers,
which is an array of three elements.
This is why in total we have here four elements and we just need to render them.
But actually here is a tricky part how we will render them.
We need somehow to merge this elements and randomize them.
It doesn't make any sense to show the user answers exactly in the same order.
And this is actually a question where we will put our correct answer at the first place or at the last
place.
It is wrong.
We really need to make it randomly.
So here is how we can do it correctly.
Actually, we might write this logic directly here and just shuffle all our answers based on our current
question.
This is totally fine, but we can make it better because we have our state and we don't want to write
our business logic inside component.
We want to move it out.
This is why we want to jump inside context quiz.
And actually here I want to create new property answers.
And inside this property we will store all answers for the current question, which actually means that
by default, we need to set here answers for the first question which are already shuffled.
And then every single time when we click on next question, we need to update them there.
This is the correct way because in this case, our component simply listen to our answers and don't
need to write any logic.
So what I want to do now is build the helper which will shuffle our answers.
This is why here inside source we can create one more file and we can name it helpers.
Dot JS And the idea is that here we can create all functions that we need across our application.
For example, here we can say that we have a function, shuffle answers and here as an argument we are
getting our current question.
And actually this function doesn't have anything to do with React.
This is plain JavaScript.
So first of all here I want to get an array of unshuffled elements.
This is why here we can create Unshuffled answers and we need here to merge our incorrect answers and
correct answers.
So here we can write question dot, correct answer and here we want to spread question dot incorrect
answers.
In this case, we will spread our elements and we will get the flat array of our answers.
Now the question is how we can shuffle them.
So actually we want to randomize our elements inside array and the JavaScript.
We don't have such function, but actually we can make it easier with math random.
So what I want here, I want to return our unshuffled answers and actually here I missed s so on the
top also.
And now I want to map our elements and as you know, we have an array of strings.
This is why here we can write that we have unshuffled answer and we want here to return an object for
every single element, which means we want to transform our array of strings to an array of objects.
And here what we have inside, first of all, is sort and here I am writing Math.random.
So here inside sort, we are generating a random number and here another property will be our value
and it will be our unshuffled answer.
So why we are doing it like this?
We actually want to shuffle our elements but we can't shuffle them because they are strings.
What we are doing here, we are creating an array of objects so we store our value and some random number
and now we can sort our array of objects by this sorting number.
And then we will simply read our values back.
This is why after this we can write sort and inside sort we are passing A and B, which means that we
want to sort a sort minus B sort.
And if you don't know, this is plain JavaScript native sorting.
So after it was sorted, we need to get back our array of strings.
This is why here I am writing map and here we have our elements.
Let's just say A and here we are getting a value.
So once again what we are getting here, we have an array of strings here.
We convert it to an array of objects just to generate our sort with Math.random.
Now we are sorting this array of objects by our math.random property.
So a dot sort.
And after this we are reading our values back.
This will shuffle all our strings inside array.
Now let's use this function inside our context.
This is why I am jumping to context quiz and here inside answers we want.
Our first question.
So within the zero to generate our shuffled answers.
So here we can call our shuffle answers function.
And here I can see that I missed letter S, So you need to write here also answers.
And here inside our helpers we need to change our function to answers.
So everything is looking fine.
Now inside we want to give the first question.
In our case it will be questions zero, because here we have our array of questions and we know that
by default we are on the first question.
So this logic will return for us.
Shuffled answers.
Let's check this out.
I'm reloading the page and here is our quiz state.
As you can see now we have property answers and here are four answers for our first question.
As you can see on this slide, the first element was colorful style sheets.
Now I'm reloading it again.
And here we have cascading style sheets, which actually means that our shuffle is working.
And every single time when we initialize our initial state, we shuffle randomly our answers.
And this makes a better UI and our quiz is more interesting.
The next step that we should do is update answers when we click on Next question.
So here is our logic with next question.
And here we need to update our answers.
This is why here we can say that we have a property answers and actually we must update it only when
we are not on result page.
So here we need exactly the same check.
If we are on show results, then we simply return empty array.
In other case, we want to shuffle it.
So here we are calling shuffle answers again and inside we are passing our state dot questions.
So this is our array and inside we are passing current question index.
And just to remind you here we calculated the next current question index for our next question, which
actually means here inside answers were either getting our shuffled answers for the next question or
empty array.
Now we can simply throw this answers property inside and it will be overwritten when we click on the
next button.
And as you can see, we are writing the whole logic inside our context, and our components are still
unaware of this whole logic.
They simply subscribe to some data and dispatch some changes.
Now let's check if it's working.
So I'm reloading the page.
As you can see here, we have our answers for the first question.
So stylesheets and so on.
I am cleaning everything and hit.
Next question.
As you can see now, here is our quiz state.
And here the question is already other because current question index is one and not zero.
And here we have different answers.
So these are answers for our next question.
And actually, we already rendered here the question where in the HTML document is the correct place
to refer to external stylesheets And this is our answers and they are shuffled correctly.
And the last thing that we need to do is render our answers because for now they are mocked here and
we need to render them from our state.
So actually I want to jump directly in our components question and here is the important part.
We don't want to make our answer component stateful, which means inside answer We won't subscribe for
our state for two reasons.
First of all, here you can see that we are rendering for elements, which actually means that we don't
know what exactly answer we are rendering.
We will do it with a loop.
And secondly, every line with Usecontext is actually a subscription for our state, which actually
means if you have 1000 elements and you have subscriptions in every of them, your application won't
be that performant.
So in components where you are rendering them with loop, like for example, answers, you should not
subscribe to the state.
So let's render our answers with the loop.
This is why I will remove completely these four lines.
We don't need them.
And here I am opening brackets and writing Quiz State.
We have it on the top dot answers and these are answers that we just created.
Now we're using Map and this is plain JavaScript map and inside map we have as an argument answer.
Now here inside this function we won't return some data, but we allow it to return markup.
This is why here we must write around brackets and inside we can put some markup for every element and
it will be rendered with loop.
This is why inside we want to render our answer component and actually we want to pass something inside
because here we know that answer is our text and we want to render it inside and we already know how
we can work with props and pass something inside our components.
So here let's create a new prop and name it, answer text, and here we can assign our answer.
In this case, we know that our answer component can accept our answer text and we just need to handle
this.
Property correctly.
So you need to remember if in React, you need to render an array.
You always need to use map like this.
Now, as you can see, we have an answer text and we must jump directly inside our answer component.
So as already said, here we have our props as the first argument, but we can directly destructure
here some local property, for example, answer text, and now inside here we can render this answer
text property inside brackets.
Let's check this out.
I'm reloading the page and as you can see here, we have already four elements and they are rendered
correctly.
Now I'm reloading it again.
And as you can see, they are on different positions, which means we are shuffling our answers for
the first question correctly.
But here is one important point.
As you can see in console, we have an error and here we have a warning.
Each child in the list should have a unique key.
Actually, here we have our map and here we are rendering answer and we have exactly this error regarding
these lines.
So what React wants from us is key property on every element in the loop and React uses this information
to render elements in the array correctly.
So what we need to do, we need to provide here additional property key just for react.
And what I want to do here is as a second argument, get the index and provide it here inside the key.
In this case, we know that our index is starting from zero until three and it will be unique.
Let's reload the page.
As you can see, the error is completely gone.
But here is something important to know regarding key.
If you just write here index.
In our case it will work because we never remove elements of the array.
But it is much better to always use unique IDs here because in this case you know, okay, I'm providing
something which is really unique for React with indexes.
You will have a problem when you remove one element of the array.
In this case, all your indexes are changed and then react can't really render them correctly.
So as you can see, we successfully rendered our question and all shuffled answers.
Now I'm hitting next question and we're getting next question.
Text and all our shuffled answers for this specific question.