this is backdrop.tsx:
interface BacdropProps {
open?: string;
onClick: () => void;
}
const Backdrop: React.FC<BacdropProps> = (props) => {
let container: HTMLDivElement | null = null;
if (typeof window !== "undefined") {
const rootContainer = document.createElement("div");
const parentElem = document.querySelector("#__next");
parentElem?.insertAdjacentElement("afterend", rootContainer);
// parentElem?.after(rootContainer) this gives me same issue
container = rootContainer;
}
return container
? ReactDOM.createPortal(
<div
className={["backdrop", props.open ? "open" : ""].join(" ")}
onClick={props.onClick}
/>,
container
)
: null;
};
export default Backdrop;
this is css for Backdoor.tsx
.backdrop {
width: 100%;
height: 100vh;
background: rgba(0, 0, 0, 0.75);
z-index: 100;
position: fixed;
left: 0;
top: 0;
transition: opacity 0.3s ease-out;
opacity: 1;
}

Your code will create
div.backdropevery time whenBackdropre-render. The correct way should be create it once. The correct way is usinguseEffectto promiseReactDOM.createPortaljust be executed once. And also apply theuseRefto make surecontainerto keep the same instance in every render.Edit
I removed the detection of existence in
window, sinceuseEffectwould be executed only in client-side.Since
ReactDOM.createPortalwill create thediv.backdropoutside of the rootHTMLElement(div#next), i think just returnnullinBackdropcomponent is fine.