Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:02,260 --> 00:00:03,330
Back in this project,
2
00:00:03,330 --> 00:00:05,720
we of course have an ErrorModal.
3
00:00:06,580 --> 00:00:09,300
This is a nice little modal where I actually
4
00:00:09,300 --> 00:00:12,720
already see an opportunity to use a Fragment,
5
00:00:12,720 --> 00:00:14,240
so let's quickly do that.
6
00:00:14,240 --> 00:00:16,520
But that's of course not the focus here.
7
00:00:16,520 --> 00:00:20,130
Instead here, we can now use a Portal
8
00:00:20,130 --> 00:00:24,600
because this entire modal actually shouldn't be rendered
9
00:00:24,600 --> 00:00:26,910
in the place where it is being rendered.
10
00:00:26,910 --> 00:00:28,570
Again, let me show you what I mean.
11
00:00:28,570 --> 00:00:31,210
If we inspect the Real DOM that is being rendered
12
00:00:31,210 --> 00:00:34,780
and I trigger that modal by submitting an invalid form,
13
00:00:34,780 --> 00:00:38,090
you see the modal divs for the backdrop and for the card,
14
00:00:38,090 --> 00:00:39,730
for the modal overlay,
15
00:00:39,730 --> 00:00:42,560
are being rendered here next to that card
16
00:00:42,560 --> 00:00:44,570
that holds my form,
17
00:00:44,570 --> 00:00:46,620
instead of the root div.
18
00:00:46,620 --> 00:00:49,240
Now in this application because it's so tiny,
19
00:00:49,240 --> 00:00:51,540
that's actually not too bad.
20
00:00:51,540 --> 00:00:53,440
But of course it's easy to imagine
21
00:00:53,440 --> 00:00:58,440
that you have an application where your AddUser Component
22
00:00:58,550 --> 00:01:02,510
is not that close to the top of the whole application,
23
00:01:02,510 --> 00:01:05,180
but where it's deeply nested in some other Components
24
00:01:05,180 --> 00:01:08,810
and therefore your backdrop and your modal divs
25
00:01:08,810 --> 00:01:10,980
would also be deeply nested in some
26
00:01:10,980 --> 00:01:12,833
other content in your DOM.
27
00:01:13,720 --> 00:01:15,650
And I actually would want to have them,
28
00:01:15,650 --> 00:01:17,260
let's say, here,
29
00:01:17,260 --> 00:01:19,460
I can drag and drop them here into DevTools.
30
00:01:19,460 --> 00:01:21,630
I might wanna have that structure
31
00:01:21,630 --> 00:01:24,620
the backdrop div right below the body,
32
00:01:24,620 --> 00:01:27,090
so as a direct child of the body
33
00:01:27,090 --> 00:01:28,620
and the same for the modal,
34
00:01:28,620 --> 00:01:32,570
a direct child of the body next to that root div
35
00:01:32,570 --> 00:01:34,603
which holds the rest of our application.
36
00:01:35,860 --> 00:01:40,160
And this is something you can achieve with well, portals.
37
00:01:40,160 --> 00:01:43,720
So now that I told you that portals are that great,
38
00:01:43,720 --> 00:01:46,060
how do we actually use them?
39
00:01:46,060 --> 00:01:48,230
Portals need two things.
40
00:01:48,230 --> 00:01:52,910
You need a place you wanna port the Component to
41
00:01:52,910 --> 00:01:55,190
and then you need to let the Component know
42
00:01:55,190 --> 00:01:57,423
that it should have a portal to that place.
43
00:01:58,560 --> 00:02:00,410
Now to mark that place,
44
00:02:00,410 --> 00:02:01,980
we go into the public folder
45
00:02:01,980 --> 00:02:03,760
and there into the HTML file
46
00:02:03,760 --> 00:02:06,070
which is being rendered in the end.
47
00:02:06,070 --> 00:02:09,889
And here it's common that you add a div with an id
48
00:02:09,889 --> 00:02:13,210
which you will then use to identify this place later.
49
00:02:13,210 --> 00:02:16,080
And here I could have my backdrop-root
50
00:02:16,080 --> 00:02:18,940
and then also maybe my modal-root.
51
00:02:18,940 --> 00:02:21,390
And you could create multiple such roots
52
00:02:21,390 --> 00:02:23,370
for different kinds of Components
53
00:02:23,370 --> 00:02:25,300
that should be portaled there
54
00:02:25,300 --> 00:02:26,680
or use simplify this a bit,
55
00:02:26,680 --> 00:02:28,500
and you have your backdrop-root
56
00:02:28,500 --> 00:02:30,680
and simply your overlay-root,
57
00:02:30,680 --> 00:02:33,300
which will then hold all kinds of overlays,
58
00:02:33,300 --> 00:02:36,250
modals, site drawers, and so on.
59
00:02:36,250 --> 00:02:37,710
And that's what I'll go with.
60
00:02:37,710 --> 00:02:39,680
So I added these two divs here,
61
00:02:39,680 --> 00:02:44,040
and then I save that file and go back to my Components.
62
00:02:44,040 --> 00:02:46,080
Now let's work on the ErrorModal,
63
00:02:46,080 --> 00:02:49,060
and let's tell React that this actually
64
00:02:49,060 --> 00:02:50,963
should be portaled somewhere.
65
00:02:52,240 --> 00:02:54,050
For that to make this very easy,
66
00:02:54,050 --> 00:02:56,980
I will actually add a constant here
67
00:02:57,820 --> 00:02:59,140
which we'll name Backdrop,
68
00:02:59,140 --> 00:03:01,070
and this will be a new Component,
69
00:03:01,070 --> 00:03:04,570
and I'll add it in this same file because in this app,
70
00:03:04,570 --> 00:03:06,940
I only use this Backdrop Component
71
00:03:06,940 --> 00:03:09,400
in conjunction with my modal.
72
00:03:09,400 --> 00:03:12,080
So I'll store all those Components in one big file,
73
00:03:12,080 --> 00:03:15,330
but you could also split it into multiple Component files,
74
00:03:15,330 --> 00:03:17,520
especially, if you would use the Backdrop
75
00:03:17,520 --> 00:03:20,790
in conjunction with other Components as well.
76
00:03:20,790 --> 00:03:22,940
Here, I'll only use it there though.
77
00:03:22,940 --> 00:03:25,530
So then I have my props and now here,
78
00:03:25,530 --> 00:03:30,453
I will return that div which gets my backdrop class.
79
00:03:32,170 --> 00:03:36,890
Now I'll also add my ModalOverlay Component here
80
00:03:37,750 --> 00:03:42,750
which gets props and there I will return this Card
81
00:03:43,990 --> 00:03:46,893
and I'll actually cut this like this.
82
00:03:48,760 --> 00:03:50,340
So I basically split my modal
83
00:03:50,340 --> 00:03:51,920
into two separate Components now,
84
00:03:51,920 --> 00:03:55,160
Backdrop and Modal Overlay because that will make working
85
00:03:55,160 --> 00:03:57,383
with portals much easier.
86
00:03:58,610 --> 00:04:01,040
We can also remove the backdrop div down there
87
00:04:01,040 --> 00:04:03,220
in the ErrorModal now.
88
00:04:03,220 --> 00:04:06,780
So what do we now do here,
89
00:04:06,780 --> 00:04:10,320
in the end here in that Fragment,
90
00:04:10,320 --> 00:04:13,410
we can add an expression because we're still inside
91
00:04:13,410 --> 00:04:15,020
of JSX code here.
92
00:04:15,020 --> 00:04:16,760
And we now wanna call a method
93
00:04:16,760 --> 00:04:19,490
which is actually not defined on React
94
00:04:19,490 --> 00:04:22,820
but on another library that comes together with React,
95
00:04:22,820 --> 00:04:25,003
the React DOM library.
96
00:04:25,940 --> 00:04:28,160
You can imagine React being the library
97
00:04:28,160 --> 00:04:32,281
that has all the React features, state management,
98
00:04:32,281 --> 00:04:33,770
onsen, baked-in.
99
00:04:33,770 --> 00:04:38,340
And React DOM uses React to bring that logic
100
00:04:38,340 --> 00:04:41,750
and these features into the web browser.
101
00:04:41,750 --> 00:04:45,560
So to make them compatible to working with the DOM,
102
00:04:45,560 --> 00:04:49,260
put in other words, the React library itself doesn't care
103
00:04:49,260 --> 00:04:52,630
whether you run it in an environment that has a DOM
104
00:04:52,630 --> 00:04:55,150
or if you would use it to build a native app.
105
00:04:55,150 --> 00:04:57,490
And for example, you can use React Native
106
00:04:57,490 --> 00:04:58,800
in conjunction with React,
107
00:04:58,800 --> 00:05:00,750
to build native mobile apps.
108
00:05:00,750 --> 00:05:02,640
I do have a separate course on that though.
109
00:05:02,640 --> 00:05:04,960
So let's not worry about that here.
110
00:05:04,960 --> 00:05:09,960
So React DOM is kind of the adapter for React to the browser
111
00:05:11,150 --> 00:05:14,820
and therefore since now we're going to portal something
112
00:05:14,820 --> 00:05:17,050
into a different place in the real DOM,
113
00:05:17,050 --> 00:05:19,860
we need to import from React DOM.
114
00:05:19,860 --> 00:05:24,860
So import something from react-dom
115
00:05:25,460 --> 00:05:30,460
and that something here can just be ReactDOM.
116
00:05:30,497 --> 00:05:32,110
So you can give this any name you want.\,
117
00:05:32,110 --> 00:05:34,250
but since I named my React import React,
118
00:05:34,250 --> 00:05:35,833
I'll name this ReactDOM.
119
00:05:37,656 --> 00:05:42,587
And on React DOM, you can now call a createPortal method.
120
00:05:44,620 --> 00:05:49,380
Now the createPortal method takes two arguments.
121
00:05:49,380 --> 00:05:54,380
The first one is your React node that should be rendered.
122
00:05:55,080 --> 00:06:00,080
And here I can render my Backdrop, let's say, like this.
123
00:06:02,210 --> 00:06:05,170
Important here it wants JSX,
124
00:06:05,170 --> 00:06:08,140
so you don't parse just Backdrop like this,
125
00:06:08,140 --> 00:06:13,140
instead, you really render it like this.
126
00:06:13,800 --> 00:06:15,180
This is also very convenient
127
00:06:15,180 --> 00:06:17,100
because this allows me of course,
128
00:06:17,100 --> 00:06:21,200
to forward my onClick prop here
129
00:06:23,540 --> 00:06:27,470
and get access to props onConfirm
130
00:06:27,470 --> 00:06:30,420
which I need to parse here to ensure
131
00:06:30,420 --> 00:06:32,003
that everything still works.
132
00:06:34,400 --> 00:06:37,030
So I can now set onClick here in my ErrorModal
133
00:06:37,030 --> 00:06:40,267
and forward the function I get on the onConfirm prop to
134
00:06:40,267 --> 00:06:43,583
the onClick prop inside of that new Backdrop Component.
135
00:06:44,510 --> 00:06:49,510
Now the second argument of createPortal is a pointer
136
00:06:50,470 --> 00:06:53,790
to that container in the real DOM where this elements
137
00:06:53,790 --> 00:06:55,773
should be rendered in.
138
00:06:56,660 --> 00:07:01,240
And in my case, I of course want to render my backdrop here
139
00:07:01,240 --> 00:07:03,933
in that backdrop-root Component.
140
00:07:05,870 --> 00:07:10,630
So back in ErrorModal, here we need to select this
141
00:07:10,630 --> 00:07:15,020
and we don't just parse backdrop-root or anything like that.
142
00:07:15,020 --> 00:07:16,970
Instead, we really select the element
143
00:07:16,970 --> 00:07:18,130
where it should be rendered to,
144
00:07:18,130 --> 00:07:20,330
and for this, we use a DOM API.
145
00:07:20,330 --> 00:07:24,840
We use document.getElementById for example,
146
00:07:24,840 --> 00:07:28,073
and get access to the backdrop-root.
147
00:07:29,690 --> 00:07:34,690
So we really get access to a real HTML DOM element,
148
00:07:35,460 --> 00:07:36,900
a DOM node here.
149
00:07:36,900 --> 00:07:41,300
And we do this with API that is provided by the browser,
150
00:07:41,300 --> 00:07:44,400
document.getElementbyId has nothing to do with React,
151
00:07:44,400 --> 00:07:49,020
we really get access to a real DOM element with this API.
152
00:07:49,020 --> 00:07:50,910
Normally we don't use that in React
153
00:07:50,910 --> 00:07:52,630
because we let React to everything,
154
00:07:52,630 --> 00:07:55,410
but here we explicitly need to use this.
155
00:07:55,410 --> 00:07:57,740
By the way, just as we need it,
156
00:07:57,740 --> 00:08:01,343
an element selected like this in index JS.
157
00:08:02,190 --> 00:08:04,740
There we also rendered the root Component
158
00:08:04,740 --> 00:08:05,890
with the render method,
159
00:08:06,850 --> 00:08:09,760
into a place selected with getElementbyId.
160
00:08:09,760 --> 00:08:11,220
We're using the same logic now
161
00:08:11,220 --> 00:08:13,940
but now we're not rendering an element there
162
00:08:13,940 --> 00:08:16,430
but instead inside of an existing application,
163
00:08:16,430 --> 00:08:18,530
which is already being rendered by React,
164
00:08:18,530 --> 00:08:20,100
we portal.
165
00:08:20,100 --> 00:08:24,870
We move the HTML content that is about to be rendered
166
00:08:24,870 --> 00:08:26,203
into a different place.
167
00:08:28,920 --> 00:08:31,970
With that let me reformat this and save it.
168
00:08:31,970 --> 00:08:34,240
And if we now go back and I click on Add User,
169
00:08:34,240 --> 00:08:37,150
you'll see the backdrop appears.
170
00:08:37,150 --> 00:08:39,010
The modal does not because I haven't added
171
00:08:39,010 --> 00:08:41,700
the logic for this yet but the backdrop does.
172
00:08:41,700 --> 00:08:42,870
And in the Elements tab,
173
00:08:42,870 --> 00:08:44,490
we see that in the backdrop-root,
174
00:08:44,490 --> 00:08:46,503
we now got the modal backdrop.
175
00:08:47,590 --> 00:08:49,520
And now it will always be there,
176
00:08:49,520 --> 00:08:52,710
no matter where you would use your ErrorModal
177
00:08:52,710 --> 00:08:53,970
in your JSX code.
178
00:08:53,970 --> 00:08:57,250
No matter how deeply nested it is in other elements,
179
00:08:57,250 --> 00:08:58,620
it will always be here,
180
00:08:58,620 --> 00:09:01,640
which is of course very close to the body.
181
00:09:01,640 --> 00:09:03,650
We need this marker here though,
182
00:09:03,650 --> 00:09:06,080
but we could have also selected the body itself
183
00:09:06,080 --> 00:09:09,800
if we really wanted it as a direct child of body.
184
00:09:09,800 --> 00:09:12,020
But I think this is a bit easier to understand
185
00:09:12,020 --> 00:09:15,120
which is why I use these extra Hook divs,
186
00:09:15,120 --> 00:09:16,770
if you wanna call them like this.
187
00:09:17,940 --> 00:09:20,860
Now let's repeat this for the actual overlay,
188
00:09:20,860 --> 00:09:23,360
for that I'll add a new expression here,
189
00:09:23,360 --> 00:09:28,360
ReactDOM.createPortal and here I wanna render
190
00:09:28,450 --> 00:09:31,740
my ModalOverlay Component
191
00:09:31,740 --> 00:09:35,540
and my ModalOverlay Component needs a bunch of props
192
00:09:35,540 --> 00:09:37,550
which I now of course wanna forward.
193
00:09:37,550 --> 00:09:39,310
It needs a title,
194
00:09:39,310 --> 00:09:42,820
it needs a content and it needs onConfirm.
195
00:09:42,820 --> 00:09:44,630
So I'll just forward this,
196
00:09:44,630 --> 00:09:48,410
I'll forward the title which I get on props.title,
197
00:09:48,410 --> 00:09:51,780
the message, which I get on props.message,
198
00:09:51,780 --> 00:09:56,220
I'll get to my onConfirm as the last one I think,
199
00:09:56,220 --> 00:09:57,583
props.onConfirm
200
00:09:58,600 --> 00:10:00,520
'cause actions of course is not a prop.
201
00:10:00,520 --> 00:10:02,700
So props.onConfirm is the last one.
202
00:10:02,700 --> 00:10:04,360
Now I'm forwarding all of this.
203
00:10:04,360 --> 00:10:06,500
And now of course, we also just as with
204
00:10:06,500 --> 00:10:09,030
the backdrop need to let React DOM know
205
00:10:09,030 --> 00:10:12,190
where it should render this HTML content
206
00:10:12,190 --> 00:10:13,490
that needs to be rendered.
207
00:10:14,740 --> 00:10:17,193
For that I'll use document.getElementbyId
208
00:10:17,193 --> 00:10:19,720
and select my overlay-root,
209
00:10:19,720 --> 00:10:23,133
which was that other div I created in the index HTML file.
210
00:10:24,740 --> 00:10:26,030
And with that saved,
211
00:10:26,030 --> 00:10:27,690
if I reload and click Add User,
212
00:10:27,690 --> 00:10:31,080
we see the modal and interaction with
213
00:10:31,080 --> 00:10:33,060
the backdrop doesn't work as I can tell,
214
00:10:33,060 --> 00:10:34,340
I will need to fix this,
215
00:10:34,340 --> 00:10:35,910
but with the modal it works
216
00:10:35,910 --> 00:10:39,020
and we see everything is rendered in the divs
217
00:10:39,020 --> 00:10:40,190
where it should be rendered
218
00:10:40,190 --> 00:10:43,743
and no longer nested in our other HTML code.
219
00:10:45,070 --> 00:10:47,113
So let's quickly fix that backdrop.
220
00:10:48,940 --> 00:10:51,910
Yeah, I should, of course forward this on onConfirm here
221
00:10:51,910 --> 00:10:56,510
because I use onConfirm here instead of that backdrop.
222
00:10:56,510 --> 00:10:59,410
So I should set an onConfirm prop,
223
00:10:59,410 --> 00:11:01,880
but with that it now works
224
00:11:01,880 --> 00:11:05,360
and I can close it by clicking on the backdrop again.
225
00:11:05,360 --> 00:11:06,400
So that's the portal.
226
00:11:06,400 --> 00:11:07,850
And the idea really just is
227
00:11:07,850 --> 00:11:11,143
that the rendered HTML content is moved somewhere else.
228
00:11:12,060 --> 00:11:13,780
In your JSX code,
229
00:11:13,780 --> 00:11:17,290
you now use that ErrorModal just as you did before,
230
00:11:17,290 --> 00:11:18,740
nothing changed here.
231
00:11:18,740 --> 00:11:22,810
In Add User, I still have my error model here,
232
00:11:22,810 --> 00:11:24,830
but it's now rendered.
233
00:11:24,830 --> 00:11:28,460
Its HTML code is now rendered in a different place.
234
00:11:28,460 --> 00:11:32,150
We use that ErrorModal just as we used it before.
235
00:11:32,150 --> 00:11:34,070
And that's the cool thing about the portal.
236
00:11:34,070 --> 00:11:35,700
Nothing changes there,
237
00:11:35,700 --> 00:11:38,010
we can communicate with it as we did before,
238
00:11:38,010 --> 00:11:41,690
we can use it as if it would be rendered here.
239
00:11:41,690 --> 00:11:43,203
It just isn't.
240
00:11:44,180 --> 00:11:45,510
All the word for note,
241
00:11:45,510 --> 00:11:49,470
React DOM createPortal can be used anywhere
242
00:11:49,470 --> 00:11:53,060
where you would otherwise use JSX code.
243
00:11:53,060 --> 00:11:54,720
Of course wrapped in curly braces
244
00:11:54,720 --> 00:11:56,930
because we're calling JavaScript code here,
245
00:11:56,930 --> 00:11:59,000
but we could have just rendered
246
00:11:59,000 --> 00:12:00,810
the backdrop here otherwise, right?
247
00:12:00,810 --> 00:12:02,860
That would have been all our alternative.
248
00:12:03,870 --> 00:12:06,820
So wherever you would normally just use the Component,
249
00:12:06,820 --> 00:12:08,570
you can use createPortal to portal,
250
00:12:09,453 --> 00:12:13,410
to move that Component's HTML content somewhere else,
251
00:12:13,410 --> 00:12:16,560
only in the actual DOM that is being rendered.
252
00:12:16,560 --> 00:12:18,690
In JSX, in your Components,
253
00:12:18,690 --> 00:12:19,710
you continue working
254
00:12:19,710 --> 00:12:22,143
with those Components as you did before.
19777
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.