Loading video player...
In the last lesson, we looked at a
common issue in React applications.
Passing the same data through multiple
layers of components, even though only
one component actually needs it. This is
the prop drilling problem. Now, let's
see how React solves this with something
called context. Context is a React
feature that lets you share data across
your component tree without having to
manually pass props through every
intermediate component. A simple way to
think about context is that it lets you
broadcast a value at a high level and
any component nested inside can
subscribe to it directly. To understand
this feature clearly, we will first
recreate the prop drilling scenario.
Then replace all the unnecessary props
with context. And to give us a head
start, I've created a new project called
context demo with the components already
created. The code is available in the
GitHub repo. But let me walk you through
the setup. We'll start with the app
component. Within the app component,
we've defined a user object with name
Bruce Wayne, role admin, and theme dark.
The app component doesn't need this data
for itself. But the header component is
a child of app. So we pass it down. The
header is defined in header.jsx.
It renders the header element and H2
title and then the navigation bar
component. Again, header doesn't use the
data itself. It simply forwards it to
navigation bar. The navigation bar
component is defined in navigation
bar.jsx.
We have the nav element and h3
navigation and then the user menu
component. Same story here. Another
component forwarding props it doesn't
need. It passes user to user menu which
is defined in user menu.jsx.
The user menu component is also a
middleman. It has a div, an h4 and then
the avatar component. It passes the user
data it receives to avatar which is
defined in avatar.jsx.
And finally the avatar component which
is the only one that actually needs the
data. It displays the welcome message
using the username. We have recreated
the header section of this component
tree. When you run the application you
should see welcome Bruce Wayne from the
avatar component but also headings from
all the other components. We have the
dashboard text from the app component
header from the header component.
navigation from the navigation bar
component and user menu from user menu
component. But what's important here is
noticing how many layers the user object
travel through header navigation bar and
user menu have no use for this data yet
they're forced to accept it and pass it
along. This is the prop drilling problem
we talked about and this is exactly the
type of problem context is designed to
fix. Step one, create a new file called
user context.jsx
within the source folder. At the top,
import create context from React and
invoke it. Create context gives us a
special object that React uses to share
data without manual prop forwarding.
Let's call it user context and export
it. So export const user context is
equal to create context. Step two, wrap
the part of the application that need
access to the data. In this case,
everything under the app component. So
in app.tjsx, JSX import user context
from dot / user context and wrap the
entire component tree with it. User
context opening and closing tags. This
right here is often referred to as the
context provider. Next, specify a prop
called value on user context and pass in
the user object. The value prop is what
we are providing or broadcasting. Any
component nested inside this user
context can now access the user data
directly. Which means we can remove the
user prop from header. We can also
remove the prop from navigation bar and
we can remove it from user menu as well.
In user menu, remove user and the prop
to avatar. Now let's update avatar to
use context instead of props. To consume
the context value, we need to use
another react hook called use context.
import it from react.mp import within
curly braces. Use context from react.
Along with use context, we also need to
import the user context we created
earlier. So import user context from dot
/ user context. In the component we call
use context and we pass it our user
context. This returns the value that is
broadcast at the top of the tree which
is the user object in our case. So const
user is equal to use context. We can now
bind this to our JSX instead of the user
prop. Save all the files, refresh the
browser, and you can see everything
still works as expected. Welcome, Bruce
Wayne. But look at how clean the code
is. We don't need to pass user through
every level. The only components that
know about user are app which provides
it and avatar which consumes it. Header,
navigation bar and user menu are
blissfully unaware of the user data
passing through them. Now let me show
you something important. What happens if
we remove the provider at the top of the
tree? So if I comment out user context
and refresh the browser, you can see the
app doesn't work because avatar tries to
read user.name but receives undefined.
There is no provider giving it a value.
To fix this, we can provide a fallback
value by passing a default to create
context.
Pass in a user object with default
values. Name is going to be guest, role
is going to be visitor and theme is
going to be light. Now if there is no
provider in the tree, avatar shows
welcome guest instead of crashing. This
can be helpful for testing components in
isolation. But in real apps, you
typically want to wrap the tree with the
context provider because the default
value is static and can't be updated. So
let's restore the provider in app.tjsx
and go back to the expected behavior.
And we're back to welcome Bruce Wayne.
So let me quickly summarize what we've
done. We created a user context object
that we can use to broadcast data to the
entire component tree. We wrapped the
app component with user context provider
and passed the user object as a value.
We then used the use context hook in
avatar to consume the user data directly
from the context.
Now everything works as expected, but
notice we're using a static user object
here. In the next lesson, we'll make
this even more powerful by combining
context with state. So the data becomes
dynamic and updatable throughout the
application. We'll create a context that
provides not just data but also
functions to modify that data.
Github - https://github.com/gopinav/React-19-Tutorials Become a Fullstack Developer with Scrimba - https://scrimba.com/fullstack-path-c0fullstack?via=Codevolution Follow me + Twitter - https://twitter.com/CodevolutionWeb Business - codevolution.business@gmail.com Context and useContext Hook in React 19