I am trying to open a React Portal, but I'm having some issues:
Here is where the open button is located:
return (
<div id="mainContent">
<table>
<td> <button onClick={() => { setIsPortalOpen(!isPortalOpen); }}>{row.original.title}</button> </td>
</table>
{isPortalOpen && (
<Window>
<MyPortal />
</Window>
)}
</div>
)
When I click the button, a window does open, but it is blank and only shows a title of: "A react portal window"
And only contains an empty div: div="window-container">
Here is the function that contains the Portal:
const [isPortalOpen, setIsPortalOpen] = useState(false);
function MyPortal() {
return ReactDOM.createPortal(
<div id="portal_ProjectDetails">
<div>Project Details</div>
<div>HEY THERE THIS IS A TEST OF THE PORTAL SYSTEM</div>
</div>,
document.body
)
}
Here is the code for Window.js:
import React from "react";
import ReactDOM from "react-dom";
export default class Window extends React.Component {
constructor(props) {
super(props);
this.state = { win: null, el: null };
}
componentDidMount() {
let win = window.open("", "", "width=600,height=400,");
win.document.title = "A React portal window";
let el = document.createElement("div");
el.id = "window-container";
win.document.body.appendChild(el);
this.setState({ win, el });
}
componentWillUnmount() {
this.state.win.close();
}
render() {
const { el } = this.state;
return el ? ReactDOM.createPortal(this.props.children, el) : null;
}
}
So as I said, the window does open when I click the button, but it's empty.
Also when I click the button, the content of appears at the very bottom of the parent page:
<div id="portal_ProjectDetails">
<div>Project Details</div>
<div>HEY THERE THIS IS A TEST OF THE PORTAL SYSTEM</div>
</div>
Here is my index.js:
ReactDOM.render(
<React.Fragment>
<MainProjects />
<div id="portal-root"></div>
</React.Fragment>,
document.getElementById('root')
)
But that's what I want to be in the Portal window.
So Im not quite sure why this is happening.
Is there anything I can do to fix this?
THanks!
Instead of creating a portal on body. Create a new div in your index.html and give it a id
<div id="portal-root"></div>
And change your MyPortal component to this
const [isPortalOpen, setIsPortalOpen] = useState(false);
const portalRoot = document.getElementById('portal-root')
function MyPortal() {
return ReactDOM.createPortal(
<div id="portal_ProjectDetails">
<div>Project Details</div>
<div>HEY THERE THIS IS A TEST OF THE PORTAL SYSTEM</div>
</div>,
portalRoot
)
}
So what is happening in your case is you are mounting on the body which removes all the ui and also the React's main root div.