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