In React 16.0 version, React portals were introduced. React portals come up with a way to render children components into a DOM node which typically occurs outside the DOM hierarchy of the parent component.
Before React Portals, It was very difficult to render the child component outside the hierarchy of its parent component. As, we were having one DOM element in the HTML into which we were mounting our react application, i.e., the root element of our index.html in the public folder. Basically, React mounts the App component onto the root element. It is almost a convention to have a div element with the id of root to be used as the root DOM element. Every single React component in react application falls under the root element, i.e., inside this statement.
<div id="root"></div>
But, React portal concept provides us the ability to break out of this dom tree and render a component onto a dom node that is not under this root element. Doing so breaks the convention where a component needs to be rendered as a new element and follows a parent-child hierarchy. Portals are commonly used in modal dialog boxes, hover cards, loaders, and popup messages. Below is the syntax of React portals.
Syntax:
ReactDOM.createPortal(child, container)
In the syntax above, we have two parameters the first parameter is a child that can be a React element, string, or a fragment and the second one is a container which is the DOM node (or location) lying outside the DOM hierarchy of the parent component at which our portal is to be inserted.
Advantages of React Portals:
- Event Bubbling inside a portal: Although we don’t render a portal inside the parent DOM element, its behavior is still similar to a regular React component inside the application. It can access the props and state as it resides inside the DOM tree hierarchy.
- React portals can use Context API to transfer the data in components.
Importing: To create and use portals you need to import ReactDOM as shown below.
import ReactDOM from 'react-dom';
Creating React Application:
Step 1: Create a React application using the following command.
npx create-react-app foldername
Step 2: After creating your project folder i.e. foldername, move to it using the following command.
cd foldername
Project Structure: It will look like the following.
Example: This is the example of portals. Here, we have created a button, whenever we click it shows a string.
src/App.js
import React, { Component } from 'react' import ReactDOM from 'react-dom' class Portal extends Component { render() { // Creating portal return ReactDOM.createPortal( <button style={{ marginLeft: '10px' }}> Click </button>, document.getElementById( 'portal' ) ); } } class App extends Component { constructor(props) { super (props); // Set initial state this .state = { click: '' }; // Binding this keyword this .handleClick = this .handleClick.bind( this ); } handleClick() { // This will trigger when the button // inside Portal is clicked, It updates // Parent's state, even though it is not // rendered inside the parent DOM element this .setState(prevState => ({ click: "Welcome to gfg" })); } render() { return ( <div onClick={ this .handleClick} style={{ marginLeft: '10px ' }}> <h2 style={{ color: ' Green' }}> { this .state.click} </h2> <Portal /> </div> ); } } export default App; |
public/index.html
<!DOCTYPE html> < html lang = "en" > < head > < meta charset = "utf-8" /> < link rel = "icon" href = "%PUBLIC_URL%/favicon.ico" /> < meta name = "viewport" content = "width=device-width, initial-scale=1" /> < meta name = "theme-color" content = "#000000" /> < meta name = "description" content = "Web site created using create-react-app" /> < link rel = "apple-touch-icon" href = "%PUBLIC_URL%/logo192.png" /> < link rel = "manifest" href = "%PUBLIC_URL%/manifest.json" /> < title >React App</ title > </ head > < body > < noscript > You need to enable JavaScript to run this app. </ noscript > < div id = "root" ></ div > < div id = "portal" ></ div > </ body > </ html > |
Output:
Explanation: We create a state with an empty string and a function handleClick which sets the value of the state to “Welcome to gfg”. The latter gets triggered as an onClick event when we click on the button which has been rendered outside the root DOM node.
When do we need them?
We mainly need portals when a React parent component has a hidden value of overflow property(overflow: hidden) or z-index style, and we need a child component to openly come out of the current tree hierarchy.
Following are the examples when we need the react portals:
- Dialogs
- Modals
- Tooltips
- Hovercards
In all these cases, we’re rendering elements outside of the parent components in the DOM tree.
Reference: https://reactjs.org/docs/portals.html