Hey guys in this lesson we're going to be creating a login flow. And very often when you're creating 1
these kind of screens you'll want to show different components depending on whether the user was logged 2
in or if they were logged out. 3
So for example, if they were not logged in and they go to your website you probably want to show them 4
the login screen like this. 5
But if they were logged in then maybe you would want to instead show a different message or a different 6
component. 7
And that's the goal of this lesson. 8
We're going to learn the techniques to show different React components depending on some sort of condition. 9
In this example when the user is not logged in, we show them the login form and if they are, we simply 10
just greet them. 11
This is what we're going to be building 12
so head over to the course resources and get hold of the starting sandbox and then fork it. 13
All right. 14
So if we take a look inside the components folder you can see that there is a single App.js. And 15
let's say that we had at the top here a variable right? Called isLoggedIn and we set it to false to begin. 16
And once the user goes through authentication, then this variable gets switched to true. 17
So what we want is we want to check the value of this boolean, isLoggedIn, and if it was true we'd render 18
this and if was false we render this form. 19
So how can we do this? 20
Have a think about how you might be to able achieve this with what you already know. You might have thought 21
of creating a function 22
right? 23
So let's call it renderConditionally and this function is going to check to see if the isLoggedIn 24
is equal to true. 25
But because this is simply a boolean which is equal to false or true, there's actually no point adding 26
this and we can simply just check it like so. 27
But I'll leave it in for now to make it very very clear that we're checking for a condition here. If 28
logged in is true, 29
well in this case we're going to return a component 30
right? 31
So I'm just going to cut that out from there and then return it here. 32
But else namely if they are not logged in or if this is equal to false, then we're going to return this 33
form component instead, like so. And then inside our div let's just make it a non self closing div. 34
So sometimes when you hit save and code sandbox it does these automatic formats which can be helpful 35
but sometimes it's not. 36
And inside this div I'm going to open up a set of JSX curly braces and I'm going to call my function 37
renderConditionally. And then add the parentheses to actually call it. 38
So now if we take a look at our website it shows the which is meant to say hello. 39
And this is because our isLoggedIn variable is set to true. 40
Now if I set it to false you can see immediately instead of that we end up with our username, password 41
and login form. 42
So this is one way of achieving this but you can see we're doing it in quite a lot of lines of code 43
right? 44
And it's not the most elegant. Given that this is probably something we're going to be doing quite frequently 45
in React checking the value of a particular property and then rendering different components depending 46
on the value of that property, 47
there's some better ways that we can do this to begin. 48
It probably makes sense to extract this form component into a separate component by itself instead of 49
leaving it as just plain HTML. Because this can be reused 50
and the thing you should always think about is that each component should have a single responsibility. 51
And this comes from something called the single responsibility principle which is something that's quite 52
central to computer programming. I'll link to this Wikipedia article if you want to read a bit more about 53
it. 54
But once you're done let's head back into our sandbox. And I want to challenge you to create a new component 55
called login which is going to contain this entire form component and then create a another component 56
called input which is going to contain each of these input components. 57
Remember that the inputs have different attributes with different values 58
so you might want to use some props and make sure that you can reuse your input component. 59
Pause the video and try to complete this challenge. 60
All right. 61
So it's always good getting more practice and getting more used to the syntax. 62
Let's go ahead and start off by creating a new file and I'm gonna call that login. 63
jsx. And inside this file I'm going to import React from react and then I'm going to create my function 64
called Log in 65
and this is going to return that form component that we had from over here. 66
So cut it out from the App. 67
jsx and finally we're going to export this as the default. 68
Now 69
let me head back into my App.jsx, import my Login from ./Login and instead of returning 70
that previous long thing, I'm going to simply return a Login component. 71
That's the first step completed and I've extracted the Login component as a separate component. 72
Then the next thing was to extract an input component so that we can reuse each of these inputs. So let's 73
add the boilerplate. And this input component is going to return one of these inputs from my form. 74
like so. And then let's go ahead and export it and import it inside my Login. So now instead of using 75
each of these separate input HTML component, I'm going to use my input component that I created 76
myself. 77
And we have two inputs currently that we want to render. 78
One has a type of text, 79
the other has a type of password. 80
One has a place holder of username and the other has a placeholder password. 81
So both of these attributes have different values that we need. 82
So it makes sense to create those as props. 83
So we'll create a prop called type and we'll create a prop called placeholder. Now the type for my first 84
input is going to be text and the placeholder is going to be Username. And then I'm going to have a 85
second input which has a type of password and a placeholder of password as well. 86
So now I can go into my input component, catch those props that's being passed over, delete the repeated 87
elements and then change my type to use the prop. 88
So add my curly braces and use my props.type and my props.placeholder. 89
Now if we refresh our website, it should look exactly the same. But we've now separated our concerns so 90
that we have the input component which just deals with each of these input fields, we've got our log 91
in component which has an entire login form and then we've got our App.js which has our conditional 92
functionality. 93
Now our code is a little bit shorter but not much. 94
One of the things I want to do is I want to be able to carry out this functionality inline, 95
so at the place where I need it to be rendered namely pretty much here. 96
But notice how if I go ahead and delete where I call my function renderConditionally, and instead I 97
copy and paste my IF statement into here, 98
it's not going to work. 99
I get an error. 100
And the problem is that remember when we use JSX, everything that goes inside these curly braces must 101
be an expression. 102
And this is not an expression. 103
This is a statement. 104
So if you recall back when we first introduced JSX, I recommended watching a video which explained 105
the difference between expressions and statements. Statements perform some sort of action and common 106
examples of statements include loops, switch statements or if else statements. 107
Think about the ones which have a keyword. In contrast an expression just resolves to a single value. 108
Wouldn't it be nice if we could convert our if else statement into an expression so that we can use 109
it here? 110
If only we had an expression in our JSX that still has the same logic namely checking if our users 111
logged in or not. 112
Well luckily for us Javascript has something called the ternary operator. 113
The ternary operator looks something like this. 114
It's got a condition which we define such as is sky == to blue? Or in our case, is that variable 115
isLoggedIn equal to true? 116
And then we have a question mark and after the question mark we say we'll do this if it's true such 117
as render the . And then after a colon, we get to specify what it should do if the condition was false 118
such as rendering our input component. So for example I live in London. 119
So whenever it's cloudy it's probably going to rain. 120
So internally I probably have a ternary operator in my brain which says if isCloudy is true then bring 121
an umbrella, 122
otherwise bring sunscreen. So the syntax comprises of the question mark and the colon and putting the 123
conditions and the expressions in the right places. 124
And that really is the beauty of the syntax. Instead of a statement 125
we now have three expressions. The condition is an expression, bring umbrella is an expression and bring 126
sunscreen is also an expression. 127
Therefore the whole thing is also just an expression. 128
Let's go ahead and have some practice with this. 129
In our case the condition is this one right here that we're checking in our IF statement. And then the 130
thing to do if it's true is to create an . 131
And the thing to do if it's false is to create a login component. We can refactor this IF statement 132
into a ternary operator like this. 133
First we have our condition which is being checked which is this one right here and then we add a question 134
mark. 135
Effectively you could read this as, "isLoggedIn true? 136
Well if so then let's create an component." And then we add a colon which means everything that comes 137
after the colon is what to do 138
if it's false. 139
So return a login component instead. 140
And now if I simplify this and bring it all onto one line then you can see it looks like this. If is 141
LoggedIn equals true, render in h1. 142
If login is not true then render the login component. 143
So if I switch this now to a true, you'll see I get the h1 being rendered instead. 144
And if this was false then it starts rendering that login component. And in fact I can simplify this 145
even more because this itself is a boolean. 146
We can simply evaluate whether if this is true or false and we don't even need this check. 147
So try it out yourself and see this ternary operator in action. Now 148
sometimes you might not want to render anything at all if a condition is not being met. 149
Let's say we create a constant called currentTime and we set that equal to new date which gets the current 150
date and time and then we call that function getHours. 151
And this if we log it, should now be equal to the current time. So in my console it's reading 13 because 152
it's 1 o'clock. 153
Now let's say I wanted to show the user a message depending on that time. 154
I'm gonna go ahead and comment out this line of code which you can keep around for reference. But what 155
I want to do is let's say if the current time was after 12 o'clock, if current time was greater than 156
12, 157
right? 158
So right now it's 1 o'clock. 159
Then I'm going to ask the user, "why are you still working?" So let's say I want to show this h1 160
"Why are you still working?" 161
And I wanted to show it as long as the time is past 12 o'clock. 162
Clearly we're not working very hard here, are we? 163
So how do I do this? 164
Well I could check to see if the current time is greater than 12, 165
this is my condition. 166
In that case, so add the question mark, I'm going to render this h1. But if it is less than 12 then 167
I don't want to show anything at all. 168
So I could achieve that by simply adding that colon which defines what it should do 169
if this condition is false and I'm going to show nothing at all. 170
I'm gonna set it as null. 171
So if I set my date to, I dunno, 2019 November the first at let's say 9 am. 172
Then it's not going to show anything on screen because this condition is not met. But as soon as the 173
time changes to past 12, let's say 18, 174
then it says "Why are you still working?" This way 175
we're able to render a component if this condition is met and render nothing 176
if that condition is not met. But there's actually an even easier way and a shorter way 177
using Javascript. And it involves the AND operator. We know that we can use the two ampersands in Javascript 178
like this where we have expression and another expression. When they're both evaluated if they're both 179
true, then this entire line of code turns into the value true. 180
Now let's say that I had a variable which was x. x happens to be equal to 5 181
at this moment in time. 182
Now if I was to use this syntax expression and expression then it might look something like this. Where 183
I'm checking if x is greater than 3 and x is less than 7, then go ahead and do something. 184
And if one of these is not true, then don't do anything at all. 185
This is usually how you would use the 186
AND operator in JavaScript code as well as other languages. 187
Now this case is easy because when x is 5, 5 is both greater than 3 and less than 7 188
so this overall expression evaluates to true. But what happens if x was equal to 1 instead? 189
Well 1 is not greater than 3. 190
So that first expression is already false. 191
And so to save time, Javascript doesn't even bother evaluating the next expression because as long as 192
one of the expressions is false where an AND operator is in use, then the whole line is equivalent to 193
false. 194
So a lot of React code leverages this fact and we end up with something that looks like this. On the 195
left hand side 196
we can have a condition and then we have the two ampersands for the AND operator, and then on the right 197
hand side we have an expression which will be evaluated as long as the condition is true. 198
But if the condition was false then it's not going to evaluate the right hand side at all, 199
so it's not going to be carried out. As an example over here 200
instead of using this ternary operator and passing null when this condition is false, we can simply delete 201
the ternary operator and just add two ampersands here. 202
This does exactly the same thing. 203
Let me explain why. 204
So the current time is 18 hours or 6PM. When the code runs down to this line, it checks 'is 18 greater 205
than 12?' 206
Well that's obviously true. 207
So it goes ahead and evaluates the right hand side of the 208
AND operator. And this line of code actually gets carried out and put onto the screen. And in React 209
that means it gets rendered. But if this left hand side of the ampersand was false, let's turn this to 210
9 o'clock again. 211
But because the AND operator requires both sides to be true, 212
if the left hand side is already false then there's no point even looking at the right hand side. 213
So this right hand side basically gets skipped. And in React 214
that means nothing gets rendered 215
which is the same as null. Depending on your own level of comfort with this line of code 216
you can choose to use it but you don't have to. 217
You can achieve the same thing using the ternary operator and a null for the false condition. 218
But out in the wild when you see a lot of React code, you'll see people using this a lot. 219
Don't get confused. 220
They're not trying to check if these things are both true. 221
They're actually trying to render something only when this left hand side condition is true. 222
All right. 223
So now that you've seen the theory, in the next lesson you're going to be applying it yourself and tackling 224
a challenge to be able to use the ternary operator and the AND operator. 225
So all of that and more, I'll see you there.