Afrikaans
Akan
Albanian
Amharic
Arabic
Armenian
Azerbaijani
Basque
Belarusian
Bemba
Bengali
Bihari
Bosnian
Breton
Bulgarian
Cambodian
Catalan
Cebuano
Cherokee
Chichewa
Chinese (Simplified)
Chinese (Traditional)
Corsican
Croatian
Czech
Danish
Dutch
English
Esperanto
Estonian
Ewe
Faroese
Filipino
Finnish
French
Frisian
Ga
Galician
Georgian
German
Greek
Guarani
Gujarati
Haitian Creole
Hausa
Hawaiian
Hebrew
Hindi
Hmong
Hungarian
Icelandic
Igbo
Indonesian
Interlingua
Irish
Italian
Japanese
Javanese
Kannada
Kazakh
Kinyarwanda
Kirundi
Kongo
Korean
Krio (Sierra Leone)
Kurdish
Kurdish (Soranî)
Kyrgyz
Laothian
Latin
Latvian
Lingala
Lithuanian
Lozi
Luganda
Luo
Luxembourgish
Macedonian
Malagasy
Malay
Malayalam
Maltese
Maori
Marathi
Mauritian Creole
Moldavian
Mongolian
Myanmar (Burmese)
Montenegrin
Nepali
Nigerian Pidgin
Northern Sotho
Norwegian
Norwegian (Nynorsk)
Occitan
Oriya
Oromo
Pashto
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Punjabi
Quechua
Romanian
Romansh
Runyakitara
Russian
Samoan
Scots Gaelic
Serbian
Serbo-Croatian
Sesotho
Setswana
Seychellois Creole
Shona
Sindhi
Sinhalese
Slovak
Slovenian
Somali
Spanish
Spanish (Latin American)
Sundanese
Swahili
Swedish
Tajik
Tamil
Tatar
Telugu
Thai
Tigrinya
Tonga
Tshiluba
Tumbuka
Turkish
Turkmen
Twi
Uighur
Ukrainian
Urdu
Uzbek
Vietnamese
Welsh
Wolof
Xhosa
Yiddish
Yoruba
Zulu
Back in this project,
we of course have an ErrorModal.
This is a nice little modal where I actually
already see an opportunity to use a Fragment,
so let's quickly do that.
But that's of course not the focus here.
Instead here, we can now use a Portal
because this entire modal actually shouldn't be rendered
in the place where it is being rendered.
Again, let me show you what I mean.
If we inspect the Real DOM that is being rendered
and I trigger that modal by submitting an invalid form,
you see the modal divs for the backdrop and for the card,
for the modal overlay,
are being rendered here next to that card
that holds my form,
instead of the root div.
Now in this application because it's so tiny,
that's actually not too bad.
But of course it's easy to imagine
that you have an application where your AddUser Component
is not that close to the top of the whole application,
but where it's deeply nested in some other Components
and therefore your backdrop and your modal divs
would also be deeply nested in some
other content in your DOM.
And I actually would want to have them,
let's say, here,
I can drag and drop them here into DevTools.
I might wanna have that structure
the backdrop div right below the body,
so as a direct child of the body
and the same for the modal,
a direct child of the body next to that root div
which holds the rest of our application.
And this is something you can achieve with well, portals.
So now that I told you that portals are that great,
how do we actually use them?
Portals need two things.
You need a place you wanna port the Component to
and then you need to let the Component know
that it should have a portal to that place.
Now to mark that place,
we go into the public folder
and there into the HTML file
which is being rendered in the end.
And here it's common that you add a div with an id
which you will then use to identify this place later.
And here I could have my backdrop-root
and then also maybe my modal-root.
And you could create multiple such roots
for different kinds of Components
that should be portaled there
or use simplify this a bit,
and you have your backdrop-root
and simply your overlay-root,
which will then hold all kinds of overlays,
modals, site drawers, and so on.
And that's what I'll go with.
So I added these two divs here,
and then I save that file and go back to my Components.
Now let's work on the ErrorModal,
and let's tell React that this actually
should be portaled somewhere.
For that to make this very easy,
I will actually add a constant here
which we'll name Backdrop,
and this will be a new Component,
and I'll add it in this same file because in this app,
I only use this Backdrop Component
in conjunction with my modal.
So I'll store all those Components in one big file,
but you could also split it into multiple Component files,
especially, if you would use the Backdrop
in conjunction with other Components as well.
Here, I'll only use it there though.
So then I have my props and now here,
I will return that div which gets my backdrop class.
Now I'll also add my ModalOverlay Component here
which gets props and there I will return this Card
and I'll actually cut this like this.
So I basically split my modal
into two separate Components now,
Backdrop and Modal Overlay because that will make working
with portals much easier.
We can also remove the backdrop div down there
in the ErrorModal now.
So what do we now do here,
in the end here in that Fragment,
we can add an expression because we're still inside
of JSX code here.
And we now wanna call a method
which is actually not defined on React
but on another library that comes together with React,
the React DOM library.
You can imagine React being the library
that has all the React features, state management,
onsen, baked-in.
And React DOM uses React to bring that logic
and these features into the web browser.
So to make them compatible to working with the DOM,
put in other words, the React library itself doesn't care
whether you run it in an environment that has a DOM
or if you would use it to build a native app.
And for example, you can use React Native
in conjunction with React,
to build native mobile apps.
I do have a separate course on that though.
So let's not worry about that here.
So React DOM is kind of the adapter for React to the browser
and therefore since now we're going to portal something
into a different place in the real DOM,
we need to import from React DOM.
So import something from react-dom
and that something here can just be ReactDOM.
So you can give this any name you want.\,
but since I named my React import React,
I'll name this ReactDOM.
And on React DOM, you can now call a createPortal method.
Now the createPortal method takes two arguments.
The first one is your React node that should be rendered.
And here I can render my Backdrop, let's say, like this.
Important here it wants JSX,
so you don't parse just Backdrop like this,
instead, you really render it like this.
This is also very convenient
because this allows me of course,
to forward my onClick prop here
and get access to props onConfirm
which I need to parse here to ensure
that everything still works.
So I can now set onClick here in my ErrorModal
and forward the function I get on the onConfirm prop to
the onClick prop inside of that new Backdrop Component.
Now the second argument of createPortal is a pointer
to that container in the real DOM where this elements
should be rendered in.
And in my case, I of course want to render my backdrop here
in that backdrop-root Component.
So back in ErrorModal, here we need to select this
and we don't just parse backdrop-root or anything like that.
Instead, we really select the element
where it should be rendered to,
and for this, we use a DOM API.
We use document.getElementById for example,
and get access to the backdrop-root.
So we really get access to a real HTML DOM element,
a DOM node here.
And we do this with API that is provided by the browser,
document.getElementbyId has nothing to do with React,
we really get access to a real DOM element with this API.
Normally we don't use that in React
because we let React to everything,
but here we explicitly need to use this.
By the way, just as we need it,
an element selected like this in index JS.
There we also rendered the root Component
with the render method,
into a place selected with getElementbyId.
We're using the same logic now
but now we're not rendering an element there
but instead inside of an existing application,
which is already being rendered by React,
we portal.
We move the HTML content that is about to be rendered
into a different place.
With that let me reformat this and save it.
And if we now go back and I click on Add User,
you'll see the backdrop appears.
The modal does not because I haven't added
the logic for this yet but the backdrop does.
And in the Elements tab,
we see that in the backdrop-root,
we now got the modal backdrop.
And now it will always be there,
no matter where you would use your ErrorModal
in your JSX code.
No matter how deeply nested it is in other elements,
it will always be here,
which is of course very close to the body.
We need this marker here though,
but we could have also selected the body itself
if we really wanted it as a direct child of body.
But I think this is a bit easier to understand
which is why I use these extra Hook divs,
if you wanna call them like this.
Now let's repeat this for the actual overlay,
for that I'll add a new expression here,
ReactDOM.createPortal and here I wanna render
my ModalOverlay Component
and my ModalOverlay Component needs a bunch of props
which I now of course wanna forward.
It needs a title,
it needs a content and it needs onConfirm.
So I'll just forward this,
I'll forward the title which I get on props.title,
the message, which I get on props.message,
I'll get to my onConfirm as the last one I think,
props.onConfirm
'cause actions of course is not a prop.
So props.onConfirm is the last one.
Now I'm forwarding all of this.
And now of course, we also just as with
the backdrop need to let React DOM know
where it should render this HTML content
that needs to be rendered.
For that I'll use document.getElementbyId
and select my overlay-root,
which was that other div I created in the index HTML file.
And with that saved,
if I reload and click Add User,
we see the modal and interaction with
the backdrop doesn't work as I can tell,
I will need to fix this,
but with the modal it works
and we see everything is rendered in the divs
where it should be rendered
and no longer nested in our other HTML code.
So let's quickly fix that backdrop.
Yeah, I should, of course forward this on onConfirm here
because I use onConfirm here instead of that backdrop.
So I should set an onConfirm prop,
but with that it now works
and I can close it by clicking on the backdrop again.
So that's the portal.
And the idea really just is
that the rendered HTML content is moved somewhere else.
In your JSX code,
you now use that ErrorModal just as you did before,
nothing changed here.
In Add User, I still have my error model here,
but it's now rendered.
Its HTML code is now rendered in a different place.
We use that ErrorModal just as we used it before.
And that's the cool thing about the portal.
Nothing changes there,
we can communicate with it as we did before,
we can use it as if it would be rendered here.
It just isn't.
All the word for note,
React DOM createPortal can be used anywhere
where you would otherwise use JSX code.
Of course wrapped in curly braces
because we're calling JavaScript code here,
but we could have just rendered
the backdrop here otherwise, right?
That would have been all our alternative.
So wherever you would normally just use the Component,
you can use createPortal to portal,
to move that Component's HTML content somewhere else,
only in the actual DOM that is being rendered.
In JSX, in your Components,
you continue working
with those Components as you did before.
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.