1
00:00:00,820 --> 00:00:04,580
React16 introduces a new way
of rendering into the DOM.
2
00:00:04,580 --> 00:00:07,560
You can render children into
a DOM element that exists
3
00:00:07,560 --> 00:00:11,720
outside of your apps main DOM tree
with a new feature called Portals.
4
00:00:11,720 --> 00:00:17,050
For example, in your index.html template,
you'll usually have a div with the id
5
00:00:17,050 --> 00:00:23,130
root, which is where your entire app is
rendered into the DOM via ReactDOM.render.
6
00:00:23,130 --> 00:00:29,520
Well, to create a portal, you add a second
element that's a sibling of your root div.
7
00:00:29,520 --> 00:00:33,286
So I'll create a div
with the id my-portal.
8
00:00:37,267 --> 00:00:41,857
Then you can render specific parts
of your component tree inside
9
00:00:41,857 --> 00:00:45,687
the sibling div with the new
createPortal function.
10
00:00:45,687 --> 00:00:50,217
Over in app.js inside the App div,
I'll create
11
00:00:50,217 --> 00:00:55,315
a JavaScript expression with
a set of curly brackets.
12
00:00:55,315 --> 00:00:59,989
Then call ReactDOM.createPortal.
13
00:01:04,509 --> 00:01:08,014
Since I'm calling ReactDOM.createPortal,
14
00:01:08,014 --> 00:01:12,929
I'll need to import ReactDOM from
ReactDOM at the top of app.js.
15
00:01:19,789 --> 00:01:24,960
The create portal function accepts
two arguments, child and container.
16
00:01:24,960 --> 00:01:29,860
The first argument child is
the content you want to render.
17
00:01:29,860 --> 00:01:34,560
So I'll render an
with the text
Hello from inside the portal!
.
18
00:01:40,380 --> 00:01:44,016
The second argument
container is the DOM element
19
00:01:44,016 --> 00:01:47,330
where the content is going to render.
20
00:01:47,330 --> 00:01:52,890
So to render the h1
inside the my-portal div,
21
00:01:52,890 --> 00:01:58,172
I'll pass it document.getElementById and
22
00:01:58,172 --> 00:02:01,512
specify the my-portal id.
23
00:02:04,570 --> 00:02:12,140
So now we see the h1 content in the app
and when I inspect the page in Dev Tools,
24
00:02:12,140 --> 00:02:17,470
notice how the h1 is being rendered
outside of the main app component.
25
00:02:17,470 --> 00:02:20,557
The portal is rendering it
inside the my-portal div.
26
00:02:21,770 --> 00:02:22,977
So, as you can see,
27
00:02:22,977 --> 00:02:27,191
createPortal provides a hook into
HTML that's outside the root div.
28
00:02:31,293 --> 00:02:33,203
As mentioned in the React docs,
29
00:02:33,203 --> 00:02:37,238
portals are useful when a parent
component has an overflow hidden or
30
00:02:37,238 --> 00:02:42,290
z-index style, but you need the child
to visually break out of its container.
31
00:02:42,290 --> 00:02:47,480
So a handy use case for portals is when
creating modal windows or overlays.
32
00:02:47,480 --> 00:02:52,690
In the project files,
I've setup a component named Modal.
33
00:02:52,690 --> 00:02:55,361
So in the return statement,
34
00:02:55,361 --> 00:03:00,493
I'll create a portal with
ReactDOM.createPortal.
35
00:03:03,195 --> 00:03:08,316
I'll pass it this.props.children
as the child argument.
36
00:03:11,316 --> 00:03:12,464
And once again,
37
00:03:12,464 --> 00:03:17,940
document.getElementByID('my-portal') as
the container argument.
38
00:03:17,940 --> 00:03:20,784
So I'll simply copy it from app.js.
39
00:03:22,130 --> 00:03:26,840
Since this Modal component returns
a portal via createPortal,
40
00:03:26,840 --> 00:03:28,830
you can place it anywhere in your app and
41
00:03:28,830 --> 00:03:32,773
it will always render its children
inside the my-portal div.
42
00:03:32,773 --> 00:03:39,910
For example, I'll import Modal in app.js,
with import Modal
43
00:03:42,870 --> 00:03:48,260
from '.components/Modal'.
44
00:03:48,260 --> 00:03:53,019
And the return statement I'll delete
the portal we created earlier,
45
00:03:53,019 --> 00:03:57,305
then I'll render the Modal by
including the Modal component.
46
00:04:01,205 --> 00:04:07,022
As the Modal content,
I'll add a div with the class modal.
47
00:04:12,922 --> 00:04:18,542
And inside the div, the text,
This is the Modal Window.
48
00:04:21,904 --> 00:04:26,714
I have already written the CSS for
the Modal class in the stylesheet, so
49
00:04:26,714 --> 00:04:31,560
in the browser we see the the Modal Window
overlay the entire page.
50
00:04:31,560 --> 00:04:38,620
Even though the Modal portal is defined
and created from within the app component,
51
00:04:38,620 --> 00:04:42,530
it is rendered outside the component,
as you can see here in Dev Tools.
52
00:04:42,530 --> 00:04:44,816
It's rendered inside the my-portal div.
53
00:04:48,676 --> 00:04:51,232
What's interesting about portals is that
54
00:04:51,232 --> 00:04:56,490
the components they render are recognized
as regular child components of the app.
55
00:04:56,490 --> 00:05:00,040
In other words, even though portal
can be anywhere in the DOM tree,
56
00:05:00,040 --> 00:05:03,890
it behaves like a normal React
child in every other way.
57
00:05:03,890 --> 00:05:09,480
For instance, an event triggered from
inside a portal still propagates or
58
00:05:09,480 --> 00:05:11,110
bubbles up to the parent component.
59
00:05:11,110 --> 00:05:16,711
For example, I'll add a handleClick
method to the app component that logs,
60
00:05:16,711 --> 00:05:18,877
I was clicked to the console.
61
00:05:30,038 --> 00:05:32,631
Then I'll give apps main app div and
62
00:05:32,631 --> 00:05:36,358
onClick event that calls
the handleClick method.
63
00:05:39,578 --> 00:05:44,699
And inside the Modal component I'll
include the button with the text Close.
64
00:05:49,739 --> 00:05:53,582
The button is being passed
through the portal, so
65
00:05:53,582 --> 00:05:58,270
you'll see it rendered
inside the my-portal div.
66
00:05:58,270 --> 00:06:03,620
We added the onClick to the parent
app div inside root, so
67
00:06:03,620 --> 00:06:06,940
the elements are not
ancestors in the DOM tree.
68
00:06:06,940 --> 00:06:12,090
But notice in React Dev Tools that
the content passed through the portal
69
00:06:12,090 --> 00:06:16,230
still exists in the React tree, regardless
of its position in the DOM tree.
70
00:06:16,230 --> 00:06:20,080
The Modal component is
still a child of app.
71
00:06:20,080 --> 00:06:26,300
So clicking the button logs,
I was clicked to the console.
72
00:06:26,300 --> 00:06:30,950
The click event bubbles up and is caught
by the parent app component's onClick.
73
00:06:30,950 --> 00:06:33,620
It triggers the handleClick
method regardless of whether it's
74
00:06:33,620 --> 00:06:34,277
inside a portal, neat.