23
loading...
This website collects cookies to deliver better user experience
ReactDOM.createPortal(child, container)
public/index.html
file and type:<div id="root"></div> <!-- this is root node -->
<div id="portal-root"></div> <!-- this node portal node -->
Modal.js
. In this file, write the code to create a modal.import ReactDOM from "react-dom";
export default function Modal() {
const portalDOM = document.getElementById("portal-root");
return ReactDOM.createPortal(<div>Modal Portal</div>, portalDOM);
}
App.js
file of the React application.import React from "react";
import "./App.css";
import Modal from "./components/modal";
class App extends React.Component {
render() {
return (
<div>
<Modal />
</div>
);
}
}
App.js
file renders the modal that you created. If you inspect the code using the browser dev tool, you will see that it is evident that the modal has its div
element.overflow: hidden
or z-index
styling settings.div
above rootdiv
.<div id=”modal”></div>
<div id=”root”></div>
Modal.js
. This component will act like a modal, and you can put content inside it.import React from "react";
import { createPortal } from "react-dom";
const modalRoot = document.getElementById("modal");
class Modal extends React.Component {
constructor(props) {
super(props);
// Create div for this modal
this.element = document.createElement("div");
}
// Append div to the div#modal
componentDidMount() {
modalRoot.appendChild(this.element);
}
/**
* Make sure to remove the div when it is closed, and save the memory.
*/
componentWillUnmount() {
modalRoot.removeChild(this.element);
}
render() {
return createPortal(this.props.children, this.element);
}
}
export default Modal;
import React from "react";
import Modal from "./Modal";
export default class Home extends React.Component {
constructor(props) {
super(props);
this.state = {
showModal: false,
};
}
toggleModal = () => {
this.setState({
showModal: !this.state.showModal,
});
};
render() {
const { showModal } = this.state;
return (
<React.Fragment>
<button className="modal-toggle-button" onClick={this.toggleModal}>
{!showModal ? "Open Modal" : "Close Modal"}
</button>
{showModal ? (
<Modal>
<h1>Sample Heading</h1>
<p>Sample Paragraph</p>
<button className="modal-close" onClick={this.toggleModal}>
X
</button>
</Modal>
) : null}
</React.Fragment>
);
}
}
showModal
property to false. The Modal will be visible at the click of the button.<html>
<body>
<div id=”app-root”></div>
<div id=”modal-root”></div>
</body>
</html>
#app-root
will be able to catch a bubbling event from its sibling node #modal-root
as both are sibling containers in the DOM.const appRoot = document.getElementById("app-root");
const modalRoot = document.getElementById("modal-root");
class Modal extends React.Component {
constructor(props) {
super(props);
this.el = document.createElement("div");
}
}
import React from "react";
class Parent extends React.Component {
constructor(props) {
super(props);
this.state = { clicks: 0 };
this.handleClick = this.handleClick.bind(this);
}
componentDidMount() {
modalRoot.appendChild(this.el);
}
componentWillUnmount() {
modalRoot.removeChild(this.el);
}
render() {
return ReactDOM.createPortal(this.props.children, this.el);
}
}
handleClick()
will fire when you click the button in Child. Keep in mind that the button is not the immediate descendant in the DOM hierarchy.handleClick() {
this.setState(state => ({
clicks: state.clicks + 1
}));
}
render() {
return (
<div onClick={this.handleClick}>
<p>Number of clicks: {this.state.clicks}</p>
<Modal>
<Child />
</Modal>
</div>
);
}
onClick
attribute.function Child () {
return (
<div className="modal">
<button>Click</button>
</div>
);
}
ReactDOM.render(<Parent />, appRoot);