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.