Press "Enter" to skip to content

Learn React & Material UI – #15 Context API (React 16.3+)


hi everyone welcome back to cold realm
in this video we’re gonna talk about
context API now you might have heard the
term unidirectional dataflow what that
basically means in the context of react
is that data always flows in one
direction up from a parent component
down to a child you might have also
heard the expression stayed up props
down and that basically means that any
shared data between two components needs
to be lifted up to a parent component
and that parent component needs to
communicate the data through properties
down to those two child components and
this is obviously done through
properties now this works fine for
simple applications in more complex
applications people face what’s known as
global state and this often refers to
the data that is being shared by
multiple segments of the user interface
that data needs to be centralized in a
single place now that place is often
referred to as the single source of
truth it practice it often centralized
in a single root component that is going
to be a container component and will
also hold the store for the application
in our exercise database the stateful
component is the app component and it
basically contains all the applications
state that all of the components down
the tree are going to use now because
it’s often difficult to pass down the
data to properties people often use open
source libraries for state management
such as redux blocks mob acts and
there’s a lot of other ones as well but
for a small to medium-sized application
a third-party library might be an
overkill because it introduces a lot of
boilerplate code that you don’t
necessarily need if you just have a
handful of components you could
obviously still use properties so for
example in our application over here we
have a dialog for creating exercises now
that dialog needs to know about the
categories of muscles that the
application provides so the drop-down
needs to know about all the categories
that are available in the application
now those categories are centralized in
store JS file we import those categories
as muscles and then we pass them down to
all the other components in this case
we’re passing down the muscles to the
header the header component is going to
pass down the properties to create
dialog heaven the dialog itself is also
going to pass down those properties to
the form now the challenge in this case
is that we want to pass down the muscles
from the app.js file so from the app
component down to the dialog component
but the dialog component is a child of
header and so we have to first pass down
the properties to the header component
as we do in App J’s file over here so
even though the header component doesn’t
need to know about muscles and it
doesn’t need to know about the on
exercise create function it still has to
accept those properties because in this
case this component acts as a middleman
it accepts those two props and then it
passes them down to the dialog you can
probably already see that the header
component doesn’t actually need to know
about those two properties in fact it
doesn’t even use them and it can really
care less about them now in this case
it’s only one component but imagine if
you had more components in between if
your dialog is deeply nested down the
tree you’re gonna have to pass down
those two properties to every single
intermediate component in between so the
question really becomes is there a way
to pass the data from a single root
component which in this case is the app
component down to any child regardless
of how far that component is buried down
the tree now the answer is actually yes
so if we switch to the react
documentation over here I’m gonna click
on dogs I’ll go to advanced guides now
let’s click on context so this article
over here is gonna provide you with the
basic information about context api
context api is available in react as a
version 16 3 and its premise is fairly
simple it allows you to transmit the
data without actually having to manually
pass it down through the properties and
just like with the regular props if that
data changes then the child components
are also going to be re rendered so what
I’m gonna do over here is I’ll switch
back to our application and inside the
source directory I’m gonna create a new
file let’s call it context GS inside
this file we’re gonna have an import of
a function known as create context and
this one is gonna come from react now of
course you could also import react
itself and then you can reference create
context function off of it directly if
you wanted to all we have to do to
create a context is to basically call
that function now that function is going
to return an object so we could
basically assign it
to a variable to call it context but
it’s also useful to the structure the
two special properties off of that
object those two properties are actually
components and those are provider as
well as consumer what we can do inside
this files we can actually export those
two constants because we’re gonna be
using them throughout the app so to
demonstrate how you can actually use
those two components I’m gonna go back
to app let’s have an import statement of
provider from context now like I always
say the dodgiest extension is optional
and because of that I’m actually gonna
remove it from store as well so let’s
save that file and a copy that provider
and inside of our render method what
I’ll do is I’ll actually have that
provider component at the very top make
sure you put it at the very top of your
tree I’m going to close that same tag
and now the provider component is gonna
expect to have a single property and
it’s called value now value is going to
contain the value for your context we’re
gonna create a method called get context
so I’m gonna add it as a method to the
class this one is gonna return an object
we can basically extract all the states
so I’ll do three dots this state and we
can also pass down knee muscles so let’s
do muscles well this is gonna do is it’s
gonna create an object with the muscles
property as well as everything that’s
inside this state and at the beginning
it’s gonna contain the exercises it’s
also gonna contain these selected
exercise the provider component in this
case is going to allow consumers to
subscribe to the context now let’s
actually make use of the context inside
of dialog so I’m going to go to dialog
GS and then at the very top I’m gonna
have an import statement of consumer
we’re gonna have to grab it from the
context we’ll have to go to levels up
and now to consume the context we’re
gonna grab the consumer component we’re
gonna place it at the very top of the
tree just like the provider so I’m going
to close off the consumer tag and now
the consumer component is going to
expect a render prop function so we’re
gonna have to provide a function and
that function is going to have a single
argument that argument refers to the
value that you pass from the app compo
so whatever you pass down to the value
prop as your context is also going to be
available in a consumer through the
value prop in your render function so
I’m going to grab the fragment over here
and I paste it into the render problem
so what I’ll do is for this value I’m
going to extract mussels out of it I’m
not going to eat destructure mussels
from the props anymore because we’re
gonna rely on the mussels on the context
I’m gonna save the file right now and in
fact we don’t need to pass the muscles
through the header anymore so I can
actually remove them from over here
inside of header I don’t need to
destructure the mussels anymore and I
don’t need to pass them down to the
dialog either so after removing those
muscles that can actually go back to the
UI let’s click on the plus icon and now
if you expand the drop down dialog you
can see that the mussels still show up
and now just to reiterate those mussels
come from the app component they’re
being passed down in the GATT context
method and they’re being extracted from
the store at the top over here now aside
from passing data we can also pass
functions so for example in this case
the dialog needs to know about the
oncreate function and this one is being
passed down from the header in the
header inherits that function from app
over here so let’s make sure we add it
to the context as well I’m going to
create an on creates property on the
context we’ll set it to this handle
exercise create and this will basically
be a reference to the function so
whenever you invoke that on create
function as a method like that it’s
actually going to internally invoke this
handle exercise created so we don’t have
to pass down that function through
properties anymore I’m gonna remove it
from the header element over here I’m
gonna save this file I’ll remove it from
the header component itself so in this
case we’ll just render the dialogue
itself we don’t need to pass any
properties to it so I’m gonna save the
file and back in dialogue we’re actually
gonna face a bit of a challenge over
here because we can obviously access the
oncreate function inside of the consumer
right so instead of the render method
but we actually need to be able to
access that function in handle form
submit now one way to go about this
would be to
create a higher-order component and this
is exactly what I’m gonna do so go back
to contacts GS what I’ll do is I’ll
create a new export this will be a
higher-order component or in essence
just a helper function I’ll call it with
context the way I’d like to use this
function is let’s say I have a dialog
component it’s my hobby dollar constant
when I do an export default of that
dialog component what I’d like to do is
I’d like to call Atwood context function
and I’d like to pass the dialog down to
that function and this is just like
calling for instance with router just
like you would do in react router
library for example or just like calling
with width in material UI they all kind
of follow the same pattern so this
constant over here needs to be a
function which is going to need to
accept a component and then it’s going
to need to return a component function
itself so the first function refers to
with context itself but with context
also needs to return an actual component
this component will be this function
over here it’s basically going to use
the consumer so we’re gonna have to put
those two tags and inside we’ll have a
render prop function this one will
actually use the component itself it’s
going to pass down the value so I’m
going to D structure the value all the
keys are gonna be D structured on the
component and passed down as properties
and we’re also gonna have to D structure
the properties themselves so for
instance if the value contains muscles
so it could be a an object like let’s
say muscles this would be an array what
this statement does is it basically
these structures that property on the
component so in the end it’s equivalent
to passing down the muscles like this
with the array of muscles inside and the
same thing goes for the properties over
here and for this JSX syntax to work we
do actually need to import react in the
end in this file so I’m gonna save it
for the time being I’m gonna go back to
dialogue instead of using consumer like
this I’m actually going to import this
helper function that we’ve just created
I’m gonna have with a contact
and then instead of exporting an
anonymous class I’m gonna actually give
this class the name let’s call it a
dialog in this case it’s actually gonna
conflict with the dialogue from material
UI but that’s not a big deal we can
actually call it create dialogue so the
bottom of the file I’m going to do a
default export of with context passing
down the create dialogue like that I’m
gonna remove the consumer like I said
because we don’t need it anymore
but at the same time we’re also gonna
need to destructure the two properties
now now in this case we only need the
muscles these ones are gonna come from
this props once again but don’t be
confused
those ones don’t actually come from the
header because we don’t pass any
properties to the dialogue from the
header the only properties we’re gonna
receive are the ones that are being
passed down from the context and now
this oncreate function is going to work
because it’s also being contained on the
props as well so I can save this well
once again I can try to create an
exercise let’s put it in arms test and
it looks like it worked so that means we
can now use contacts to access global
state in their application so to finish
this off I’m gonna refactor the app to
use contacts across the board so I’m
gonna go to footer first of all let’s
actually refactor this component to a
class-based component let’s have a
footer class let’s can extend a
component inside I’m actually going to
create a few methods so let’s have an on
index select method let’s also have a
render method as well like we did before
we’re going to return the app bar
component let’s have a return statement
now for the index this could as well be
a method too
so let’s have get index so now for the
default export I’m gonna put in the
footer component we’re also gonna wrap
it with our helper function so this is
gonna be with context like this that
we’re gonna need to import it as well so
let’s import with context this is gonna
come from context to levels up we’re
gonna need to have a component import as
well now this function is gonna need to
extract a few things from the props so
I’ll have a destructuring statement
let’s have on
lect and this one we can actually call
it on category select because this one
refers to the muscles and I can also
grab the muscles themselves so let’s
grab them from this Brock’s dysfunction
right now we’re not passing it in the
app component but we actually need to so
let me go back over here I’m gonna paste
in a new property this one is gonna
refer to your local method once again
and it’s called handle category select
I’m gonna paste it in let’s go back to
our footer I’m gonna do the same thing
for this method over here in fact it’s
going to be a function I’m gonna D
structure a few things we’re gonna need
to get our category as well as muscles
from the props and we’re gonna need to
return something so let’s return this
ternary expression over here and then
we’re gonna need to change the on select
constant to on category select to make
this work so now this index we can
actually get it from a local function so
let’s do get index and the on index
select this is actually a local method
as well so let’s reference that I know
we will have a width now this one comes
from material UI so what I’ll do is I’ll
have a destructuring statement of width
on this props once again and the muscles
were going to need to reference them as
well these ones come from the context so
once we save it we can now navigate
between the different categories as well
moving forward let’s also refactor index
J s now this component is pretty heavy
and that’s because we’re passing a lot
of different data down to that component
so let me go back to a PS I’m gonna
finalize the list of methods over here
so we also have on edit this one is
going to be this handle exercise edit we
also have on select edit this one refers
to this handle exercise select edit the
last one we also have on delete this
going to be this handle exercise delete
and I think that’s all of them let’s go
back to index what I’ll do is I’ll
actually put this into a separate
constant let’s call it exercises this
one is going to be a function so we’re
gonna do is we’re gonna have an export
at the very bottom let’s have an export
of exercises we’re gonna wrap it with
with context
and once again if we go back to the very
top of the file we’re gonna have to have
an import so let’s import with context
from context we’re gonna need to go to
levels up so now I can save the file and
then in the app component let’s make
sure we’re passing all of our data the
exercise comes from the state it’s
basically this exercise over here so we
can remove it from the props also
passing down the category this one comes
from the state as well you can see that
we’re actually extracting it from the
state over there so we can remove it
from the props again we can also remove
exercises now these exercises are
actually exercises by muscles so I think
we do need to add them to the context I
think what we can do is we can have
exercises by muscles and this is gonna
be the array from this method over here
this one is gonna take in the flat array
and it’s basically going to sort the
muscles by category now what else we
also have the edit mode that’s an estate
the muscles again this comes from
storage as files so we have on select
actually on select we do need to add
still I think this is the last method
that we missed this one it’s gonna be
this handle exercise select we have on
delete we have on select edit and then
we have on edit itself so I can now
remove all of those properties so we’re
actually reducing a code base quite a
bit I’m also gonna remove all of those
few properties from the footer as well
also gonna remove these constants we
don’t need them anymore and now instead
of index GS we need to get exercises by
muscles like this we’re gonna need to
replace them over here in the app
component we can also now remove the
fragment because we now have a provider
at the top and then I remove that we
don’t need the fragment we can remove it
from the import statement as well in the
exercises component well now it’s
actually using the context all those
properties come from this method get
context over here now we’ll still have
to pass down the properties to the form
component that’s because we have the
four component in two files one of them
is the exercises components the one
you’re seeing right now we also have the
form instead of dialog and we’re
actually passing different properties in
different cases so I think what I’ll do
is I’ll keep those two properties as
they are because they’re gonna change
based on where the form is being used
other than that
every other component uses context so I
think the refactor wasn’t too bad in the
end and I hope you enjoyed this video and I’ll see you next time

Please follow and like us: