reactjsreact-portal

Opening a new React Portal only opens an empty page with no content


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!


Solution

  • 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.