WEBVTT
0
00:00.450 --> 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
00:07.860 --> 00:14.070
these kind of screens you'll want to show different components depending on whether the user was logged
2
00:14.070 --> 00:16.140
in or if they were logged out.
3
00:16.140 --> 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
00:21.960 --> 00:24.150
the login screen like this.
5
00:24.150 --> 00:31.560
But if they were logged in then maybe you would want to instead show a different message or a different
6
00:31.560 --> 00:32.690
component.
7
00:32.910 --> 00:34.760
And that's the goal of this lesson.
8
00:34.800 --> 00:41.760
We're going to learn the techniques to show different React components depending on some sort of condition.
9
00:41.880 --> 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
00:48.690 --> 00:50.760
just greet them.
11
00:50.760 --> 00:52.170
This is what we're going to be building
12
00:52.200 --> 00:58.940
so head over to the course resources and get hold of the starting sandbox and then fork it.
13
00:59.340 --> 00:59.640
All right.
14
00:59.670 --> 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
01:06.570 --> 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
01:15.210 --> 01:23.460
And once the user goes through authentication, then this variable gets switched to true.
17
01:23.530 --> 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
01:31.390 --> 01:36.030
this
and if was false we render this form.
19
01:36.100 --> 01:38.510
So how can we do this?
20
01:38.530 --> 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
01:46.230 --> 01:47.830
of creating a function
22
01:47.850 --> 01:48.180
right?
23
01:48.240 --> 01:58.920
So let's call it renderConditionally and this function is going to check to see if the isLoggedIn
24
01:58.980 --> 02:01.020
is equal to true.
25
02:01.140 --> 02:06.720
But because this is simply a boolean which is equal to false or true, there's actually no point adding
26
02:06.720 --> 02:10.560
this and we can simply just check it like so.
27
02:10.560 --> 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
02:17.580 --> 02:19.080
logged in is true,
29
02:19.110 --> 02:23.940
well in this case we're going to return a component
30
02:23.940 --> 02:24.210
right?
31
02:24.210 --> 02:27.980
So I'm just going to cut that out from there and then return it here.
32
02:28.650 --> 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
02:36.480 --> 02:48.620
form component instead, like so. And then inside our div let's just make it a non self closing div.
34
02:48.790 --> 02:54.490
So sometimes when you hit save and code sandbox it does these automatic formats which can be helpful
35
02:54.520 --> 02:56.250
but sometimes it's not.
36
02:57.160 --> 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
03:03.220 --> 03:08.230
renderConditionally. And then add the parentheses to actually call it.
38
03:08.260 --> 03:14.870
So now if we take a look at our website it shows the which is meant to say hello.
39
03:15.070 --> 03:18.770
And this is because our isLoggedIn variable is set to true.
40
03:18.820 --> 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
03:26.110 --> 03:28.390
and login form.
42
03:28.480 --> 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
03:35.500 --> 03:36.200
right?
44
03:36.250 --> 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
03:43.150 --> 03:49.930
in React checking the value of a particular property and then rendering different components depending
46
03:49.930 --> 03:51.820
on the value of that property,
47
03:51.850 --> 03:55.970
there's some better ways that we can do this to begin.
48
03:55.990 --> 04:03.760
It probably makes sense to extract this form component into a separate component by itself instead of
49
04:03.760 --> 04:08.210
leaving it as just plain HTML. Because this can be reused
50
04:08.380 --> 04:15.400
and the thing you should always think about is that each component should have a single responsibility.
51
04:15.400 --> 04:20.380
And this comes from something called the single responsibility principle which is something that's quite
52
04:20.380 --> 04:25.930
central to computer programming. I'll link to this Wikipedia article if you want to read a bit more about
53
04:25.930 --> 04:26.070
it.
54
04:26.440 --> 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
04:33.280 --> 04:39.700
called login which is going to contain this entire form component and then create a another component
56
04:39.700 --> 04:44.740
called input which is going to contain each of these input components.
57
04:44.740 --> 04:49.060
Remember that the inputs have different attributes with different values
58
04:49.180 --> 04:54.840
so you might want to use some props and make sure that you can reuse your input component.
59
04:54.960 --> 04:57.220
Pause the video and try to complete this challenge.
60
05:01.950 --> 05:02.280
All right.
61
05:02.320 --> 05:06.040
So it's always good getting more practice and getting more used to the syntax.
62
05:06.460 --> 05:12.320
Let's go ahead and start off by creating a new file and I'm gonna call that login.
63
05:12.670 --> 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
05:20.410 --> 05:21.580
called Log in
65
05:22.060 --> 05:27.180
and this is going to return that form component that we had from over here.
66
05:27.310 --> 05:30.450
So cut it out from the App.
67
05:30.580 --> 05:35.350
jsx and finally we're going to export this as the default.
68
05:38.070 --> 05:38.460
Now
69
05:38.500 --> 05:46.670
let me head back into my App.jsx, import my Login from ./Login and instead of returning
70
05:46.670 --> 05:52.730
that previous long thing, I'm going to simply return a Login component.
71
05:52.880 --> 05:59.910
That's the first step completed and I've extracted the Login component as a separate component.
72
06:00.030 --> 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
06:08.760 --> 06:18.110
add the boilerplate. And this input component is going to return one of these inputs from my form.
74
06:18.110 --> 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
06:30.520 --> 06:38.350
each of these separate input HTML component, I'm going to use my input component that I created
76
06:38.350 --> 06:39.410
myself.
77
06:39.730 --> 06:43.560
And we have two inputs currently that we want to render.
78
06:43.570 --> 06:45.040
One has a type of text,
79
06:45.040 --> 06:46.900
the other has a type of password.
80
06:46.900 --> 06:50.740
One has a place holder of username and the other has a placeholder password.
81
06:50.830 --> 06:54.530
So both of these attributes have different values that we need.
82
06:54.550 --> 06:57.780
So it makes sense to create those as props.
83
06:57.970 --> 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
07:07.310 --> 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
07:14.660 --> 07:21.540
second input which has a type of password and a placeholder of password as well.
86
07:21.650 --> 07:29.780
So now I can go into my input component, catch those props that's being passed over, delete the repeated
87
07:29.810 --> 07:34.040
elements and then change my type to use the prop.
88
07:34.280 --> 07:43.420
So add my curly braces and use my props.type and my props.placeholder.
89
07:43.690 --> 07:51.400
Now if we refresh our website, it should look exactly the same. But we've now separated our concerns so
90
07:51.400 --> 07:57.350
that we have the input component which just deals with each of these input fields, we've got our log
91
07:57.350 --> 08:04.060
in component which has an entire login form and then we've got our App.js which has our conditional
92
08:04.060 --> 08:05.620
functionality.
93
08:05.860 --> 08:10.350
Now our code is a little bit shorter but not much.
94
08:10.660 --> 08:16.860
One of the things I want to do is I want to be able to carry out this functionality inline,
95
08:16.900 --> 08:21.550
so at the place where I need it to be rendered namely pretty much here.
96
08:22.060 --> 08:28.780
But notice how if I go ahead and delete where I call my function renderConditionally, and instead I
97
08:28.780 --> 08:32.180
copy and paste my IF statement into here,
98
08:32.410 --> 08:34.300
it's not going to work.
99
08:34.540 --> 08:36.310
I get an error.
100
08:36.310 --> 08:43.570
And the problem is that remember when we use JSX, everything that goes inside these curly braces must
101
08:43.690 --> 08:45.590
be an expression.
102
08:45.790 --> 08:48.060
And this is not an expression.
103
08:48.070 --> 08:49.550
This is a statement.
104
08:49.600 --> 08:56.620
So if you recall back when we first introduced JSX, I recommended watching a video which explained
105
08:56.620 --> 09:03.700
the difference between expressions and statements. Statements perform some sort of action and common
106
09:03.700 --> 09:08.490
examples of statements include loops, switch statements or if else statements.
107
09:08.560 --> 09:16.030
Think about the ones which have a keyword. In contrast an expression just resolves to a single value.
108
09:16.180 --> 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
09:21.910 --> 09:22.820
it here?
110
09:22.930 --> 09:29.170
If only we had an expression in our JSX that still has the same logic namely checking if our users
111
09:29.170 --> 09:30.970
logged in or not.
112
09:30.970 --> 09:35.380
Well luckily for us Javascript has something called the ternary operator.
113
09:35.380 --> 09:38.880
The ternary operator looks something like this.
114
09:39.100 --> 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
09:47.950 --> 09:50.010
isLoggedIn equal to true?
116
09:50.290 --> 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
09:57.160 --> 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
10:07.390 --> 10:13.190
such as rendering our input component. So for example I live in London.
119
10:13.250 --> 10:17.180
So whenever it's cloudy it's probably going to rain.
120
10:17.750 --> 10:25.730
So internally I probably have a ternary operator in my brain which says if isCloudy is true then bring
121
10:25.730 --> 10:26.750
an umbrella,
122
10:26.750 --> 10:34.410
otherwise bring sunscreen. So the syntax comprises of the question mark and the colon and putting the
123
10:34.440 --> 10:38.690
conditions and the expressions in the right places.
124
10:39.180 --> 10:43.230
And that really is the beauty of the syntax. Instead of a statement
125
10:43.290 --> 10:49.710
we now have three expressions. The condition is an expression, bring umbrella is an expression and bring
126
10:49.710 --> 10:52.410
sunscreen is also an expression.
127
10:52.410 --> 10:56.850
Therefore the whole thing is also just an expression.
128
10:56.850 --> 10:59.750
Let's go ahead and have some practice with this.
129
11:00.030 --> 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
11:06.780 --> 11:10.880
thing to do if it's true is to create an .
131
11:11.100 --> 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
11:18.330 --> 11:21.210
into a ternary operator like this.
133
11:21.210 --> 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
11:28.590 --> 11:29.400
mark.
135
11:29.520 --> 11:34.470
Effectively you could read this as, "isLoggedIn true?
136
11:34.580 --> 11:45.780
Well if so then let's create an component." And then we add a colon which means everything that comes
137
11:45.900 --> 11:47.810
after the colon is what to do
138
11:47.850 --> 11:49.170
if it's false.
139
11:49.170 --> 11:53.560
So return a login component instead.
140
11:53.640 --> 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
12:03.700 --> 12:08.190
LoggedIn equals true, render in h1.
142
12:08.240 --> 12:13.240
If login is not true then render the login component.
143
12:13.730 --> 12:20.070
So if I switch this now to a true, you'll see I get the h1 being rendered instead.
144
12:20.180 --> 12:27.440
And if this was false then it starts rendering that login component. And in fact I can simplify this
145
12:27.680 --> 12:31.160
even more because this itself is a boolean.
146
12:31.610 --> 12:38.680
We can simply evaluate whether if this is true or false and we don't even need this check.
147
12:38.840 --> 12:44.750
So try it out yourself and see this ternary operator in action. Now
148
12:44.770 --> 12:51.190
sometimes you might not want to render anything at all if a condition is not being met.
149
12:51.190 --> 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
12:59.650 --> 13:04.000
date and time and then we call that function getHours.
151
13:04.000 --> 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
13:13.500 --> 13:15.270
it's 1 o'clock.
153
13:15.270 --> 13:21.680
Now let's say I wanted to show the user a message depending on that time.
154
13:21.810 --> 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
13:27.060 --> 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
13:35.700 --> 13:36.050
12,
157
13:36.060 --> 13:36.360
right?
158
13:36.390 --> 13:38.860
So right now it's 1 o'clock.
159
13:39.210 --> 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
13:44.520 --> 13:47.370
"Why are you still working?"
161
13:47.550 --> 13:53.280
And I wanted to show it as long as the time is past 12 o'clock.
162
13:53.850 --> 13:56.090
Clearly we're not working very hard here, are we?
163
13:56.970 --> 13:59.340
So how do I do this?
164
13:59.340 --> 14:06.070
Well I could check to see if the current time is greater than 12,
165
14:06.090 --> 14:07.880
this is my condition.
166
14:08.040 --> 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
14:17.430 --> 14:19.070
I don't want to show anything at all.
168
14:19.350 --> 14:25.090
So I could achieve that by simply adding that colon which defines what it should do
169
14:25.110 --> 14:30.010
if this condition is false and I'm going to show nothing at all.
170
14:30.150 --> 14:31.930
I'm gonna set it as null.
171
14:32.010 --> 14:46.230
So if I set my date to, I dunno, 2019 November the first at let's say 9 am.
172
14:46.680 --> 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
14:53.610 --> 14:57.570
time changes to past 12, let's say 18,
174
14:57.570 --> 15:02.040
then it says "Why are you still working?" This way
175
15:02.040 --> 15:08.460
we're able to render a component if this condition is met and render nothing
176
15:08.460 --> 15:14.790
if that condition is not met. But there's actually an even easier way and a shorter way
177
15:14.820 --> 15:24.360
using Javascript. And it involves the AND operator. We know that we can use the two ampersands in Javascript
178
15:24.750 --> 15:32.820
like this where we have expression and another expression. When they're both evaluated if they're both
179
15:32.820 --> 15:38.840
true, then this entire line of code turns into the value true.
180
15:38.880 --> 15:45.110
Now let's say that I had a variable which was x. x happens to be equal to 5
181
15:45.120 --> 15:46.690
at this moment in time.
182
15:47.010 --> 15:54.630
Now if I was to use this syntax expression and expression then it might look something like this. Where
183
15:54.630 --> 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
16:03.300 --> 16:08.050
And if one of these is not true, then don't do anything at all.
185
16:08.070 --> 16:09.890
This is usually how you would use the
186
16:09.990 --> 16:14.940
AND operator in JavaScript code as well as other languages.
187
16:14.970 --> 16:22.380
Now this case is easy because when x is 5, 5 is both greater than 3 and less than 7
188
16:22.410 --> 16:31.620
so this overall expression evaluates to true. But what happens if x was equal to 1 instead?
189
16:31.970 --> 16:36.010
Well 1 is not greater than 3.
190
16:36.470 --> 16:39.830
So that first expression is already false.
191
16:39.830 --> 16:47.330
And so to save time, Javascript doesn't even bother evaluating the next expression because as long as
192
16:47.390 --> 16:55.640
one of the expressions is false where an AND operator is in use, then the whole line is equivalent to
193
16:55.640 --> 16:56.930
false.
194
16:57.110 --> 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
17:03.800 --> 17:04.640
left hand side
196
17:04.670 --> 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
17:10.670 --> 17:18.350
hand side we have an expression which will be evaluated as long as the condition is true.
198
17:18.350 --> 17:23.770
But if the condition was false then it's not going to evaluate the right hand side at all,
199
17:23.840 --> 17:29.750
so it's not going to be carried out. As an example over here
200
17:29.810 --> 17:38.210
instead of using this ternary operator and passing null when this condition is false, we can simply delete
201
17:38.210 --> 17:42.870
the ternary operator and just add two ampersands here.
202
17:42.890 --> 17:45.290
This does exactly the same thing.
203
17:45.320 --> 17:46.920
Let me explain why.
204
17:47.100 --> 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
17:55.400 --> 17:56.070
than 12?'
206
17:56.660 --> 17:58.660
Well that's obviously true.
207
17:58.700 --> 18:02.560
So it goes ahead and evaluates the right hand side of the
208
18:02.570 --> 18:10.950
AND operator. And this line of code actually gets carried out and put onto the screen. And in React
209
18:10.970 --> 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
18:17.750 --> 18:19.120
9 o'clock again.
211
18:19.370 --> 18:24.380
But because the AND operator requires both sides to be true,
212
18:24.380 --> 18:29.550
if the left hand side is already false then there's no point even looking at the right hand side.
213
18:29.720 --> 18:34.650
So this right hand side basically gets skipped. And in React
214
18:34.760 --> 18:37.040
that means nothing gets rendered
215
18:37.340 --> 18:44.660
which is the same as null. Depending on your own level of comfort with this line of code
216
18:44.720 --> 18:47.360
you can choose to use it but you don't have to.
217
18:47.360 --> 18:53.110
You can achieve the same thing using the ternary operator and a null for the false condition.
218
18:53.390 --> 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
18:58.400 --> 18:59.670
Don't get confused.
220
18:59.780 --> 19:03.400
They're not trying to check if these things are both true.
221
19:03.440 --> 19:07.910
They're actually trying to render something only when this left hand side condition is true.
222
19:09.060 --> 19:09.540
All right.
223
19:09.560 --> 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
19:15.770 --> 19:21.400
a challenge to be able to use the ternary operator and the AND operator.
225
19:22.130 --> 19:24.620
So all of that and more, I'll see you there.