2.4 Login Component
Login component is where our users will go to sign in and sign out. In this lesson, we'll build this login functionality!
1.Getting Started6 lessons, 27:04
2.Building the Application13 lessons, 1:29:43
3.Conclusion1 lesson, 00:44
2.4 Login Component
Now that we have our api, we can go ahead and create our login component. So I'll create a new file, src/components/login, and of course at the top we'll start with some imports. We'll import react, and we'll also import all of the functions from the API that we just created. So I'll import star as APIi from the API file. This means that we will have an API object. That will have all of our different API functions as methods on the API object. Next will export our default class. Log in and that will extend react component. And will start writing with our render function. Now before we actually write our render function, let's move back to the app.js file and we'll import the logon component. Then will replace our logon placeholder with an actual call to that logon component. Now our logging component will need to know about our user. Right. If the user is already logged in, it will need to display a log out button. Otherwise it will need to display the username and password fields and a log in button. So we're going to have to give it a user property. And we'll set this to be. And of course this will be our user state value. All right. So back in our logon component. Will start by checking to see if the user is currently logged in. So we can do this by saying if (this.props.user). And if they are logged in, we'll create a new div. We'll give it a class name of row, so that skeleton will style it correctly. And inside, we'll start with a paragraph that just says hi to the user. So we can get their username through this.props.user.name. Underneath that we'll have another paragraph, and in here we can have our sign out button. So we'll just create a button with the text Sign Out, and then we can add an onClick handler to the button. So that when this button is clicked, we will call a function. And that function will be this tall sign out. So that is what we will render. If the user is signed in. However if they're not signed in. Let's render something different. We'll render another div with the class name of row. And then inside this we'll create a paragraph and we'll put an input tag inside of this paragraph. We'll give it a class name of u-full-width. This is one of skeleton's utility classes. It will style this input element to take up the full width of the row. Will give it some place holder text. Will set a reference. So that we can access this dom element from our reactor code. And of course will set the type equal to text. I'll duplicate this line. And let's see what do we need to change? We'll set the placeholder to pass word, will set the reference to password, and will set the type to password as well. We need one more paragraph tag. And this will have two different buttons. The first button will be for signing in, so will added On Click event handler for this. Dots on union. And then of course will give it the text. Sign In. And then I'll duplicate this. And change the on click To Sign Up, and I'll change the text to Sign Up as well. If we give our watch task a second to recompile the code, and then refresh our page here in the browser, you can see that this component is displaying just fine. We have our username field and our password field, and we have our sign in and sign up buttons. However, because we haven't written our event handler functions yet, we can't actually log in or out yet. So, let's go back to our code here and write those functions. This is where we have to use our class property syntax. So, that the value of this inside the function will refer to our component instance. Because this function will be run as a dom event, we only have a single parameter event. We'll start inside this function by getting the username and password values. We can do this with the react.findDOMNode function. And we can pass this .refs.username to get the element with a ref property username. And then of course we'll the value from that DOM node. And we'll do the exact same thing for a password. Then we can call API.signin and pass it that username and password. You'll remember from our previous lesson that this will return a promise, so we can go ahead and call. Then when we get that data, what we want to do inside this callback is store the user's value. Because remember, if the user is logged out, then the value that initially gets interpolated into our index template will be null, and that of course will result in the user seeing the login form. However, after they do log in, our API request here will return the user object, allowing them to be logged in. So we need to store this user object somewhere. Now we need to store this at the app level. We need to store it in our app component. So back in our app component here, let's add another property to our login component. We're gonna call this set user, and this will just call this .setUser. Let's create a setUser function. It will take a user object as its parameter, and it will just set the state value of user to the user object that was passed in. So now, back from within logon, we can call this. So we can say this.props.setUser to data.user. Of course, remember that if this is not the correct username and password and the log in fails, then data.user will be undefined and so nothing will actually change. The user will still see the logon form. Now we want to recreate a similar function for signing up. Actually it's an extremely similar function, because we still need to get the username and password from the same text boxes. But then instead of calling API.sign in. We want to call API dott sign up. So it's modify our sign in function here a little. We'll change the parameters to be name and event, so that we're expecting a name as our first parameter. And then will change the function name from Sign in to just sign. Then down here we call API.signin. Instead of doing that we'll use the square brackets index. And we'll call API sign plus whatever the name was. So, now we can choose when we call this function. Whether we wanna call sign in or sign up. And so, we can create too a little helper functions here. We can create sign in, which we'll call this.sign, and it will use in, and it will pass the event through. And then we can create sign up, which will called this.sign with up as the first parameter. Now, our users can sign in and sign up. All right, that leaves us with just sign out, so let's create our sign out function, and this is super simple. We just want to call api.signout. And when this returns, we will do this.props.setUser and we'll set the user to null. So this way we can easily log the user out. Excellent, so with all of these functions in place, we should be able to see our code in action. I'll come back to the browser here, and I will type in a username and password. When I click sign in, nothing happens, because there's currently no user with that username and password. In fact, if I find the request here in the network tab, and we look at the response. You can see that we get the message, wrong username or password. We're not actually going to display those messages, but they're there if we wanted to. So instead of clicking sign in, let me click sign up, and you can see that immediately our log in component changes from the form to the sign out open. And you can see the requests here in the Network tab, it says signed in equals true, and it sends us our user object. Now ,we probably would not want to include that password hash value In a live application, but for our simple application we'll just ignore that. There is one problem that we have with our login feature, and that is that the users name is not actually being displayed properly. We have hi, but their name is not there at all. So if we go back to our render function, we're looking for the value this.props.user.name, but we want user.username. So if I change that and we let our code compile, now if I refresh the page, you can see that Hi Andrew is being displayed just fine. Excellent. So now our users can successfully log in and out of our application. Now we can start building actual Wiki features. And in the next lesson, we're going to look at creating new Wiki pages.