I totally understand if the last video was a little bit difficult for you and you might think now,
okay, react is too complicated, but actually we just need to go through previous video and this video
and then our development will be really like a breeze.
This is why let's talk in this video about communication of different components.
And actually, as you can see, we have a quiz.
Then inside we have question and answer.
And for now, we wrote both state and use reducer inside our quiz, which means actually that this state
is only there inside quiz.
We can't really get properties of this state inside our another components for example question or answer
which actually means if we want to pass the state or some properties from this state to our other components,
we can do it in React by using props, which actually means here we have our state and we know that
inside state we have, for example, questions and current question index.
And actually if we want to pass some information from parent component to child component in React,
we normally are using it like this.
So we're writing here.
Question And we can say here that we want to pass an array of questions inside.
So here is attribute questions and we're writing here state dot questions, which actually means that
here we wrote the local property state questions and now it is the props.
So the property of question, which means now we are passing the part of the state to our child component.
And now we can jump inside our question.
And here we are getting props, which actually means props is our first argument when we are getting
some properties inside our child component.
But normally we are not using them like this.
We want to destructure them directly.
In this case, we don't need to write props dot for example, questions.
We can directly destructure here our props and get local property questions.
It is exactly the same like just writing props dot questions, but we really want to omit props.
This is why we have this Destructuring.
Now let's console.log here our question, comma questions and let's check this out.
I'm reloading the page.
As you can see, this is our console.log question.
And you see here inside state we have questions array zero.
So this means this is an empty array and we passed it inside.
Child So this is how our components in React can communicate.
And this is exactly only the single way we simply need to pass some information from parent component
to child.
But here the huge problem now we have three levels of our components.
We have quiz, then a question and then inside question.
We have our answers.
But in a big application you can have like 5 or 10 levels of nesting inside components.
This is why we actually have a problem if we are saying, okay, this is quiz, this is our root component
here we have our state and let's say that some deeply nested component must access this information,
which means we are passing it to second level.
So the question then from the question, we need to pass it inside answer and then it is already bad
because we are passing some information just to pass it because we actually maybe not using this information
inside our question, but only inside answer.
So this is the bad pattern and the question is how we can fix it.
And in React, we have such thing, which is called react context.
Actually, this is just a way how we can access some global object, which means we have our data like
our state, for example, as a global object, and we can access this state from all our components.
And it really simplifies everything because on every level doesn't matter how deep our component is,
we can directly read this data without need to pass them through props.
And this is actually the best and most scalable way to build our application.
So what do we want to do now?
We want to move our state in this react context, how we can do this?
First of all, we must create, react context and you just need to remember react.
Context is just some global object or global property that we want to share across our application.
This is why here I want inside our source to create new folder and name it context.
So here will be all our contexts that we want to share across the application.
And our first context is quiz dot JS because actually we are making quiz and we want to store all our
properties and all our business logic inside this context.
Now the question is how we can create context inside React.
And this is really simple.
We can simply say here that we want to create our quiz context.
And as you can see, I am naming it from Big Q.
So here we have our context and we say create context and create context is just a function from React.
And here we can pass default value.
But we don't need it.
So actually to create a context, we simply call a function, create context.
This is it.
Our next step will be to get a provider.
So what is the provider?
This is special wrapper, which provides the data to all our components.
So basically the idea is that we have here our index.js and as you can see here, we have our quiz component.
And actually this is the start of our application, which means all our components are inside our quiz
component.
What we want to do now, we want to wrap this component with our provider.
So we will provide there our global value and it will be available everywhere inside this component,
which actually means the next step is to create provider.
This is why here we want to create our quiz provider.
And the main point is this is just a react function to create a component, nothing else.
So this is exactly the same.
Like we just create a simple component and here we can return some markup, but here we don't just want
some div, we want to write here quiz context that we have on the top dot provider.
So actually when we create a context, there is a property provider inside and the main idea here that
we can write value and provide here whatever value we want.
For example, we can write here a string foo and then this string will be available globally.
Let's close our quiz context and check if it's working.
So what I want to do now, I want to open on the right index.js And here I want to wrap our quiz with
this quiz provider that we just created.
So I simply write here quiz provider, and I need to close it here.
And as you can see, I'm saving it.
And here on the top you need an import of our quiz provider.
So the only thing that we did, we created additional component and put our whole application inside
this component.
Now let's check if it's working.
As you can see in browser, our page is completely blank.
Now we don't have any content.
Why is it happening?
Because actually here on the left we just returned our quiz context provider, which is just a wrapper
with some data.
We didn't render our content inside.
And as you can see here, inside Index.js, we passed inside content.
And actually this is our children, which means all content inside component.
When we are writing like this is our children and we can access them and render them if we want to.
In our case, we know that our quiz provider here is getting this props like you already saw.
And from the props here, we can destructure children and actually this children is this content.
In our case, this is a quiz which actually means now here we can return this quiz provider and render
inside children.
And after this I will close our provider.
Let's check this out.
I'm reloading the page and bam, our quiz is back.
How it is working.
Actually, when we write any markup or any component inside some other component, for example, like
here, we can access it through the children and we can do something with it.
In this case, we rendered it inside because if we don't render it, then it's not there.
So the main point what we did, we wrapped our quiz with quiz provider and in this case we can access
now this global property foo that we wrote here everywhere.
Now to get this global data inside any component we can write like this.
So we want to get our quiz state, which is our global foo property.
And for this we are using React hook, which is called use context.
And inside we must pass a context.
And we already created this.
This is our quiz context and let's check our imports.
So as you can see on the top, I have here the import of quiz context from context quiz.
This is what we just created.
And here we also need to import use context from React.
Let's check what we have inside our quiz state.
This is why I will console.log quiz state and here we have quiz state and reload our page.
And as you can see here we have quiz state foo and actually this is just a string, but it changes everything
because as you can see, we don't write anything inside our component except of this single line.
So in every component doesn't matter how deep this component is, we can just write, use context,
quiz, context, and we are getting our global property.
This is exactly what we want.
We want to store all our data business logic in a single place and access it from everywhere.
Our next step will be to move this reducer and initial state inside our context.
Because it doesn't belong here.
It belongs where our business logic is.
This is why I will just cut everything that we have here and move it inside our source context quiz.
For example, here on the top we can paste this code and now I will jump back inside our component quiz
and cut this line with use reducer, as you can see.
You.
We created our usereducer here, but it doesn't make any sense because we can't really share this state
everywhere because we created it here.
The main point is now we will create this state inside our context and then we can share this state
everywhere.
This is why I will cut these two lines.
We don't need them.
And jump back inside our context quiz.
And now here, inside our quiz provider, we can write this code.
So what we are doing here, we are using Usereducer.
We have in this file our reducer and initial state.
And now we have here state and dispatch, which actually means we can provide them and not this value
for inside as a global object, which means our value will be an array with two properties, state and
dispatch.
So actually we can remove these properties and just name it value because we know this is an array and
we provide here a value.
And if we want to provide values in React, we are providing them as a parameters in this brackets and
we just name it value.
In this case, we know we are sharing not some string foo, but we are sharing an array.
And the most important part that now we have access to our reducer stuff like state and dispatch everywhere
across the application.
And this is exactly what we wanted and this is super scalable.
Now we can jump back inside our quiz component and we know that here we are not getting only quiz state,
we are getting actually an array.
This is why I will destructure it here and now we have quiz state comma dispatch function just like
we had previously and now we don't need here on the top use reducer because now it is completely isolated
inside our provider.
Now let's check if it's working.
So I'm reloading the page and we have some errors.
First of all, here on line 15, we don't have state and this is completely fine because inside markup
we used state dot questions to pass our questions as an example.
We actually don't need to pass them anymore because we can with this single line in every single component,
access our whole state.
Let's remove this and reload it again.
So here we have our use reducer, which is not defined and this is inside our context.
So we need to jump back inside context.
And here on the top we didn't import our use reducer hook.
Let's save this.
And as you can see now, we have just a single error.
State is not defined.
So here inside quiz on the bottom we don't have actually a state because we can check this value and
this will be an array.
So I'm reloading the page and you can see what we have inside state.
This is an array with two elements.
First of all, this is our global object where we will have all our properties and the next one is our
dispatch function.
And as you can see, here is our console.log for quiz State inside our quiz component.
So this is this.
And as you can see, our component has access to our global object.
And now the most important part, we can clean our console and click here on the next question.
And as you can see, everything is working like previously.
So once again, to make it clear, we're using React context to get some global object that we can share.
And we're using Usecontext Hook everywhere to get access to this react context and is a global value.
We didn't provide just some string like foo or some object we provided the result of reducer and this
gives us possibility to have a global state and dispatch function, which means our business logic is
completely isolated inside our context and everywhere.
We simply say what we want to change.
And actually, I can promise you two things.
First of all, with this approach, you can build really scalable react applications.
And secondly, it was the difficult part of the course and all other stuff will be really easy because
we made an awesome foundation.