Heads up! To view this whole video, sign in with your Courses account or enroll in your free 7-day trial. Sign In Enroll
Well done!
You have completed React Authentication!
You have completed React Authentication!
Preview
We’ll use React’s context api to be able to provide the user’s data to any component in our app
Resources
React DevTools
Treehouse Courses and Workshops
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
Currently, when a registered user
logs in via the sign in form,
0:00
they're greeted with a generic message and
don't have the ability to sign out.
0:04
Now that we have a way to authenticate and
identify users,
0:10
we can associate data with specific users.
0:14
When an authenticated
user logs into the app,
0:17
we'll display a custom message on
the page with their name and username.
0:21
We'll also add a welcome message in
the header using their name, and
0:27
replace the navigation links with
the settings and sign out links.
0:32
To be able to display the welcome
message on the authenticated route and
0:36
navigation bar, both the authenticated and
0:42
nav components need access
to the user's data.
0:45
Currently, the user's data
is only available in the
0:49
UserSignIn component, once the user
has successfully signed in.
0:53
To provide the user's data to
multiple components in our app,
0:58
we'll use React Context API.
1:03
Context allows us to pass data to
components no matter where they
1:06
are in the component tree.
1:11
In the context folder,
open up the UserContext file.
1:13
I've already created the context
with the createContext method and
1:17
created the UserProvider component that
will provide the data throughout the app.
1:22
Right now, we haven't passed any
data to our context provider.
1:28
In index.js, our main app component
is wrapped in the UserProvider tags.
1:32
So now all components in our app can get
access to the data we pass to UserContext.
1:40
I've included a link to our React Context
API course, if you would like a refresher.
1:47
Back in UserContext,
1:52
we'll start off by creating a state
that will store the user's data.
1:54
At the top of the UserContext,
we'll import the useState
1:59
hook by adding useState
next to createContext.
2:04
At the top of UserProvider,
we'll declare the state
2:08
with const bracket,
we'll name our state authUser and
2:13
the function to update it to setAuthUser.
2:18
Set it equal to useState and
set the default value to null.
2:22
We need to set authUser
to the user's data.
2:28
Currently, in the UserSignIn component,
after the user signs in,
2:33
the server responds with the user's data,
if the correct credentials were provided.
2:38
To be able to store the user's
data in the authUser state,
2:44
we'll need to move the fetch
method into the UserContext file.
2:49
So let's cut the fetch and the if / else
statement from the handleSubmit function.
2:54
Now handleSubmit
3:03
will still need to update the error
state if the user wasn't authenticated,
3:04
or if they were authenticated, navigate
the user to the authenticated route.
3:10
So we'll add a todo comment.
3:15
Our todo will be to get
the user from UserContext.
3:19
If the user was successfully signed in,
or user does not equal null,
3:25
we'll navigate to the authenticated route.
3:30
But if sign in failed, the user will
equal null and will update errors state.
3:36
Open up UserContext and paste the code
we just cut inside the signIn function.
3:47
We now have a couple of errors.
3:54
We'll delete the set errors and
3:57
navigate since we'll have
UserSignIn handle that.
3:59
We're left with one error,
fetchOptions is not defined.
4:04
We'll go back into the user
UserSignIn component and
4:10
cut out both the fetchOptions and
encodedCredentials variables
4:14
and paste them above our fetch
method in the signIn function.
4:20
The signIn function needs access to
the user's credentials to be able to
4:25
encode it in Base 64, and
provide it to the authorization header.
4:30
So we'll add the parameter
credentials to our signIn function.
4:35
Great, we handled all the errors.
4:41
Let's finish up by completing
our if / else statement.
4:44
If our server responds to our
fetch with a status code of 200,
4:48
that means the user was authenticated and
the response contains the user's data.
4:53
We already have a line of code that takes
the response and parses it into json.
4:59
Let's then set the authUser
state equal to the user data
5:04
returned by the server with
setAuthUser and passing it user.
5:09
And lastly, we'll return user.
5:15
If our server responds
with a status code of 401,
5:20
that means the server could
not authenticate the user.
5:24
So in that case, we'll return null.
5:28
Our signIn function and authUser state
are ready to be provided to UserContext.
5:33
To do so, we'll pass
UserContext.Provider the value prop.
5:40
The data we pass to the value prop can be
accessible to any component in our app.
5:45
Let's pass value, an object that
contains the authUserState and
5:52
a property of actions,
which will hold our signIn function.
5:57
We're now able to call
the signIn function within any
6:03
component that consumes the UserContext.
6:06
Let's go back to the
UserSignIn component and
6:09
complete the to do task
we left in handleSubmit.
6:13
When the user submits the sign in form,
6:17
we'll sign them in by calling
the signIn function from UserContext.
6:19
To get access to the signIn function,
we'll need to use React's useContext hook.
6:25
The useContext hook is already being
imported at the top of our file,
6:32
so we just need to import
UserContext with import
6:39
UserContext from context/UserContext.
6:44
At the top of the UserSignIn component,
6:49
we'll get access to
the UserContext value with
6:52
const context = useContext(UserContext).
6:57
This context variable is now equal to
7:01
the object we pass to the value
prop in UserContext.Provider.
7:04
Since we only want access
to the signIn function,
7:09
we can use destructuring
to extract the actions
7:14
property from context,
with { actions }.
7:18
Now we have access to the signIn function
and we can call it in handleSubmit.
7:23
In the try block,
we'll sign in the user with
7:29
await actions.signIn() and
pass it credentials.
7:34
The signIn function returns
either the user's information,
7:39
if authenticated, or null,
if the user wasn't authenticated.
7:43
So let's store that in
a variable called user.
7:48
If the user is authenticated, we want to
navigate them to the authenticated route.
7:53
We'll add an if statement that checks if
the user variable exists. By just providing
7:58
the user variable in the if condition,
we're making sure user is a truthy value.
8:04
So user cannot be null, undefined,
zero or any other falsy values.
8:10
So if the user variable exists,
or is truthy,
8:17
then we'll navigate the user to
authenticated with navigate() and
8:21
passing it /authenticated.
8:27
else, if the user variable
is a falsy value,
8:31
then we'll update the error
state with setErrors() passing
8:35
in an array with the string,
Sign-in was unsuccessful.
8:41
I'll delete our to do comment,
save our changes, and
8:46
check to see if our sign
in feature still works.
8:50
I'll navigate to the sign in form and
enter my credentials.
8:54
Great, our sign in feature still works,
but
9:00
now the authUser state can be
accessible to any component.
9:03
We can even see if authUser
is being updated correctly by
9:07
opening up the React DevTools.
9:12
If your component list doesn't look
the same as mine, don't worry.
9:14
You can pause the video and
turn on the same filters I have.
9:19
Select the UserProvider component,
and to the right,
9:24
under hooks, we see the authUser
state with my name and username.
9:29
Great job so far.
9:33
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