Module 2: Token
In this module, we will focus on adding authentication to our app by saving our token that we get from the server upon sign up or login.
Step 1. Signup
constructor additions
Let's go into the Signup.js
file and add some things starting with the constructor:
Analysis
Note that we've added
username
andpassword
to our state. We want to set these items to empty strings to set the initial value for the state of those properties. Simply put, when a user starts the application those properties should not have values.
handleChange method
Under the constructor(note that ours is collapsed for brevity) create a handleChange
function:
Analysis
Each time the user types inside of the input, we want the state to change: 1. This function takes in the event (which is captured when the user types something into the input). 2. We call the setState
method that will allow us to change the state of the application. 3. It takes the name
field of the target, which in our case is username
and password
. Remember how we told you to note the name attribute/property in our last module? Here's a screenshot to help you visualize this:
We grab the value, which is what the user typed into the input fields for username and password.
handleChange method
Now let's add this handleChange
function to our username and password inputs in the jsx. NOTE: SOME CODE HAS BEEN OMITTED FOR BREVITY IN THE CODE BELOW. You'll need to add onChange={this.handleChange}
as in the following code:
Testing
Open up your console in the web browser and you will see the changes as you type in your React Dev Tools.
Right click inspect on whatever element you want to see the state of twice. In this case you will right click on the Sign Up element.
React devtools should go to it automatically. Make sure you're on
<Signup>
so that you can see the right state. This is a good step to take every time when changing the state, to make sure things are functioning like you want them to.You should see the following:
handleSubmit
Now we want to create a handleSubmit
function. This function will eventually serve to do a POST for our user information in a request and then get the sessionToken back in a response. For now, let's just go ahead and build a really basic handleSubmit
function directly under handleChange
:
Analysis
Notice above that we're taking in an event, and we are preventing default, which in this instance will prevent our page from refreshing when we submit the form. Also, note that handleSubmit and handleChange are both arrow functions here so that we don't have to worry about binding them in the constructor. If you DO NOT make them as arrow functions you must bind them in the constructor, so that you can access things like this.setState
.
Now that we have a basic function, let's plug this into where we will be using it, so that we can console log things out and make sure that they are working correctly.
Form Submission
You are still inside of
signup.js
.Go to the form in the render function.
Add the
onSubmit
field to the top of your form and make add the call forhandleSubmit
:
Still inside the render function, in the Form, add in a standard button after the
FormGroup
closing tag and just before theForm
closes:Now we have a basic form that logs our message to the console upon submitting.
Step 2. sessionToken
Let's review what we need to do: 1. In our Signup
and Login
components, once the user submits their information we want to log them in and store the session token. 2. Remember that we set up the capability to store and set the token in the localStorage in our App.js
, particularly by writing the setSessionState
method. Be sure to take a minute to review that file/code a little. 3. Now, we just need to pass the ability to set the sessionToken down to our Login and Signup components. We don't need to create another function to do this. We simply pass the token down as a prop. 4. The reasons for making the function in App.js
and not in both Login and Signup is that we want to store the sessionToken in the parent and not all over the application. We also don't want duplicate code. Let's go ahead and see how we can pass our functions as a prop throughout our application.
Passing Down Props
Go to
App.js
and pass in oursetSessionState
as a prop to ourAuth
component. so that we can then pass this function to the children.Login
andSignup
:Now head into your
Auth.js
. Make the following changes to theAuth
component:
We are adding props to our parameter. Remember that this is a functional component, like a function it can take in arguments to be used throughout the function.
We create a property(prop) called setToken. This will allow us to pass the token down to our
Signup
function. This is not the same as thesetToken
in theApp.js
component. It's a property that will be associated with a lower component, and it is named the same for clearly bridging the props through the unidirectional flow.These props are tethered to the
props
parameter in the parens above.When we use the dot accessor on that
props
variable, we can use access the properties fromApp.js
. Look where we call the Auth component inApp.js
:<Auth setToken={this.setSessionState}/>
We do the same process of on our Login Call.
handleSubmit additions
Now we have access to the function that we wrote in App.js
in our Signup
component. Let's open our Signup.js
and update our handleSubmit
function so that we can properly create a token:
Analysis
Let's look at what the above function is doing: 1. We're sending a fetch
request to the endpoint determined in our server, that is where we go to signup. Note that this endpoint is determined by whatever backend you're using. In your own server backend, it's declared in app.js
if you forget what you named your routes. Take some time to review your server now. A good practice is to have endpoints available in notes. 2. The method of the fetch is a POST
. 3. We're including a body
with our state information set as user. This again correlates to the backend. If your server is expecting information in this format: req.body.user.username
and req.body.user.password
, then the above will work. When making future applications this is what has to match what the backend is expecting. If the backend is expecting req.body.user.username
and req.body.user.password
and I send it req.body.spongebob.pineapple
, it doesn't know how to handle that information. 4. We're including the header Content-Type
set to application/json
. This let's our server know what type of information we are sending to it, so it can decide if it can handle it and what to do with it. 5. We're resolving the promise from fetch and calling .json()
, allowing us to turn the response into JSON when it resolves. 6. We're resolving the .json()
promise, and taking the data we get back from the server and then calling our setToken function with the sessionToken we get back in the data object.
Review
Let's look at another breakdown of the props data getting passed down through the application: 1. In App.js
we set the state of our token as an empty string. 2. In App.js
we pass our setSessionState
function as a prop from our App.js
to our Auth.js
in a property called setToken
. 3. In Auth.js
we then pass our token as a prop to Signup.js
.
Challenge: No username? Return a message:
For this challenge, we want to display a message to the user if the user hasn't added a username, this is a basic version of form validation. You don't have to have completed this before moving on. It can be done at any time.
You should see something like this:
Last updated