Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Preview
Start a free Courses trial
to watch this video
Let's go over one solution to the React context challenge.
Resources
Related Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign upRelated Discussions
Have questions about this video? Start a discussion with the community and Treehouse staff.
Sign up
How did it go?
0:00
Were you able to create the new context?
0:00
Even if you created some parts,
that's still great.
0:03
I'll walk you through how
I created the new context.
0:06
First, let's create a file in our
context folder named ThemeContext.js.
0:10
We'll create a new context using
React's createContext method.
0:19
So let's import createContext from "react".
0:24
Our context will be named ThemeContext,
so
0:28
let's write const
ThemeContext = createContext,
0:33
and set the default value to null.
0:38
And let's not forget to export it
with export default ThemeContext.
0:43
Alright, with our context created,
let's now create the provider
0:51
component that will contain all
the state and helper functions.
0:55
We'll declare the function with
1:00
export const ThemeProvider = (props),
1:02
and add a return statement.
1:12
This is going to be our
higher order component.
1:18
It will take in an existing component and
1:21
return a new component
with the context provided.
1:24
So in the return statement, let's add
opening and closing provider tags.
1:28
Inside the provider tags,
we will pass in the components
1:35
passed to the theme provider
with {props.children}.
1:41
The provider tag must
have a prop of value, so
1:47
let's add value to ThemeContext.Provider.
1:51
To pass the state and
actions to the value prop,
1:57
we must first move them over
from the App component.
2:00
So in App.js,
copy the states, useEffect and
2:04
toggleDarkMode function from App.js.
2:09
We'll also delete the useState and
2:16
useEffect hook import since the app
component will no longer need it.
2:19
In ThemeContext.js, paste the code at
the top of the ThemeProvider function.
2:24
And let's not forget to import the
useState and useEffect hook from React.
2:33
We'll add useState and useEffect right
next to our createContext import.
2:40
Now back to the provider's value prop.
2:48
The value prop will contain
an object with all the state and
2:52
all the functions needed
to manage the state.
2:56
So let's pass value
an object with curly braces.
3:00
To know exactly what to pass the value,
3:05
I like to take a look at how the app
component was passing down the props.
3:08
So in App.js we see Header
is being passed accentColor.
3:13
So let's add accent color
to the value object.
3:19
Next, we see isDarkMode,
toggleDarkMode, accentColor,
3:23
updateAccentColor, fontPercentage, and
3:28
updateFontPercentage are all being
passed to the settings component.
3:32
So back in ThemeContext.js, let's add
all those props to our value object.
3:39
First, we'll add isDarkMode.
3:46
To keep things organized, I'm going
to add a property called actions, and
3:50
actions will contain our functions.
3:55
We'll provide actions
the toggleDarkMode function.
3:59
We already passed
the accentColor to value, so
4:04
now let's pass an action
named updateAccentColor.
4:07
And its value will be the set function for
accentColor, so setAccentColor.
4:12
The last two we need to provide is
fontPercentage and updateFontPercentage.
4:21
So under isDarkMode,
we'll add fontPercentage.
4:28
In the actions object, we'll add
an action called updateFontPercentage,
4:33
and set its value to
the setFontPercentage function.
4:40
All right,
our theme context provider is all set.
4:46
To provide it to the entire app,
let's head over to index.js.
4:50
And at the top,
we'll import the ThemeProvider
4:56
with import {ThemeProvider}
from context/ThemeContext.
5:01
Just like we did for the UserProvider,
5:12
we'll wrap the app component
in the ThemeProvider.
5:15
Our theme context is now being
provided to our entire app.
5:26
Let's now use the context
in our components.
5:31
The first component we'll work
with is the Header component.
5:35
At the top of the file, let's import
the useContext Hook and the ThemeContext.
5:41
So we'll type import {
useContext } from "react" and
5:49
import ThemeContext from
context/ThemeContext.
5:56
The header component only needs
access to the accentColor state.
6:02
So we'll access that state from
the ThemeContext with const,
6:08
{accentColor} = useContext(ThemeContext).
6:15
As a reminder,
6:23
the useContext hook returns the value
prop provided to the provider tab.
6:24
And since the header component only
needed access to the accentColor state,
6:31
I destructure the object by setting
the useContext hook to {accent color}.
6:37
We'll replace props.accentColor
with just accentColor.
6:43
Since we're no longer passing
the acccentColor state to the header
6:52
component as props,
we can delete the props parameter.
6:57
In App.js,
we can delete the accentColor prop
7:03
past the header because
it no longer needs it.
7:08
Alright, let's do this again,
but with the UserSignIn component.
7:12
In UserSignin.js It looks like we're
already importing the useContext Hook.
7:18
So let's just import
the ThemeContext with import
7:27
ThemeContext from context/ThemeContext.
7:32
This component only needs access
to the accentColor state.
7:37
So let's write const { accentColor } =
7:41
useContext(ThemeContext).
7:46
Now, wherever we see props.accentColor,
7:52
we can replace it with accentColor.
7:56
And we'll remove the props
parameter from the userSignIn
8:02
component since it's no
longer using any props.
8:07
And in App.js will remove the accentColor
prop from the UserSignIn tag.
8:11
All right, let's consume the ThemeContext
in the three theme components.
8:22
AccentColor, DarkMode and FontSize.
8:28
In FontSize.js, we'll import both
the useContext Hook and the ThemeContext.
8:33
So we'll type import {
useContext } from "react".
8:41
And import ThemeContext
from context/ThemeContext.
8:49
And at the top of FontSize,
we'll consume the context with const.
8:57
And this component only needs access
to fontPercentage, accentColor,
9:03
and the action updateFontPercentage.
9:08
We'll set it equal to useContext,
themeContext.
9:12
Now, we'll remove the props parameter
from the fontSize component and
9:19
update props.fontPercentage
to fontPercentage.
9:25
props.updateFrontPercentage to
actions.updateFrontPercentage.
9:29
Lastly, I'll remove props
from props.accentColor.
9:36
This component no longer needs any props.
9:42
So we'll go up the component tree and
9:45
remove the props passed to
the FontSize component.
9:47
So, in Settings.js, we'll remove all
9:50
the props passed to the FontSize tag, and
9:55
in App.js, we'll delete fontPercentage and
10:00
updateFontPercentage.
10:06
The next component we'll work
on is the accentColor component.
10:09
In AccentColor.js, we'll import
the useContext Hook in the ThemeContext.
10:14
I'll actually just copy the import
statements from FontSize.js and
10:22
paste it at the top of AccentColor.js.
10:29
We'll consume the context with const.
10:34
And this component needs access
to the accentColor state and
10:38
the action of the accentColor.
10:42
Then set it equal to
useContext(ThemeContext).
10:46
Now, we can remove the props parameter and
10:52
remove props from props.accentColor and
10:57
change props.updateAccentColor
to actions.updateAccentColor.
11:01
All right, this component is all set.
11:09
Let's now navigate back
up the component tree,
11:12
removing the props passed to AccentColor,
starting with Settings.js.
11:16
We'll remove all the props
from the AccentColor tag.
11:23
And then App.js will remove
the props accentColor,
11:27
and updateAccentColor
from the settings tag.
11:32
Alright, we just have to consume
the context in one more component.
11:39
So in DarkMode.js,
let's paste in the useContext and
11:45
ThemeContext import statements
that we copied earlier.
11:49
At the top of the DarkMode component,
we'll consume the context with const.
11:55
And this component only needs
access to the isDarkMode state and
12:02
the action toggleDarkMode.
12:06
And we'll set it equal to
useContext(ThemeContext).
12:10
We'll remove the props parameter
from the DarkMode function.
12:15
And in the return statement, we'll
delete props from props.isDarkMode and
12:19
change props.toggleDarkMode
to actions.toggleDarkMode.
12:26
Let's navigate back up
the component tree to Settings.js.
12:33
We'll remove the props
passed to the DarkMode tag.
12:38
Our settings component is now no longer
passing props down to its children.
12:43
So we can delete the props
parameter from settings.
12:49
And in App.js, we'll remove all
the props from the Settings tag.
12:52
Our App component now looks much
cleaner and has less responsibilities.
13:01
It's just the stateless component
that renders the components.
13:06
We've made a lot of changes, so
let's make sure our app is still working.
13:11
Be sure to save all the changes we made so
far, then open the app in the browser.
13:17
I'll click the Sign In button and
fill out the input fields.
13:24
Now let's navigate over
to the settings route.
13:31
I'll turn on dark mode,
adjust the accent color to this green.
13:36
We can see that both the header and
font size accent colors have been updated.
13:41
Now, let's increase the font size to 150%.
13:48
Let's make sure the theme stays the same
even when we sign out, and it does.
13:52
We can see the UserSignIn component
also has access to the theme states.
14:00
We're all set.
14:06
Everything still works as expected.
14:08
So, how did you do?
14:10
If you didn't get it, it's alright.
14:12
Watch the previous videos and
try this challenge again.
14:15
You now know how to create a context,
provide it values and
14:19
access the values using
the useContext Hook.
14:24
In the next video, I'll recap what
you just learned in this workshop.
14:29
You need to sign up for Treehouse in order to download course files.
Sign upYou need to sign up for Treehouse in order to set up Workspace
Sign up