react runtime_error ai_generated true

Error: The portal container is not a valid DOM element. Make sure the container element exists before calling createPortal.

ID: react/portal-container-not-mounted

Also available as: JSON · Markdown · 中文
92%Fix Rate
87%Confidence
1Evidence
2023-04-12First Seen

Version Compatibility

VersionStatusIntroducedDeprecatedNotes
React 16.0+ active
React 17.x active
React 18.x active

Root Cause

ReactDOM.createPortal is called with a container that is null or undefined, usually because the target DOM element hasn't been mounted yet (e.g., document.getElementById('portal-root') returns null).

generic

中文

ReactDOM.createPortal 被调用时传递了一个 null 或 undefined 的容器,通常是因为目标 DOM 元素尚未挂载(例如 document.getElementById('portal-root') 返回 null)。

Official Documentation

https://reactjs.org/docs/portals.html

Workarounds

  1. 95% success Ensure the container element exists in the HTML before the React app mounts. Example: <div id="portal-root"></div> in index.html, then use const portalRoot = document.getElementById('portal-root'); ReactDOM.createPortal(children, portalRoot);
    Ensure the container element exists in the HTML before the React app mounts. Example: <div id="portal-root"></div> in index.html, then use const portalRoot = document.getElementById('portal-root'); ReactDOM.createPortal(children, portalRoot);
  2. 90% success Use useEffect to create the portal after the component mounts: useEffect(() => { setContainer(document.getElementById('portal-root')); }, []); Then conditionally render the portal only when container is not null.
    Use useEffect to create the portal after the component mounts: useEffect(() => { setContainer(document.getElementById('portal-root')); }, []); Then conditionally render the portal only when container is not null.
  3. 88% success For dynamic containers, create the container element in useEffect and append it to document.body: useEffect(() => { const el = document.createElement('div'); document.body.appendChild(el); setContainer(el); return () => document.body.removeChild(el); }, []);
    For dynamic containers, create the container element in useEffect and append it to document.body: useEffect(() => { const el = document.createElement('div'); document.body.appendChild(el); setContainer(el); return () => document.body.removeChild(el); }, []);

中文步骤

  1. Ensure the container element exists in the HTML before the React app mounts. Example: <div id="portal-root"></div> in index.html, then use const portalRoot = document.getElementById('portal-root'); ReactDOM.createPortal(children, portalRoot);
  2. Use useEffect to create the portal after the component mounts: useEffect(() => { setContainer(document.getElementById('portal-root')); }, []); Then conditionally render the portal only when container is not null.
  3. For dynamic containers, create the container element in useEffect and append it to document.body: useEffect(() => { const el = document.createElement('div'); document.body.appendChild(el); setContainer(el); return () => document.body.removeChild(el); }, []);

Dead Ends

Common approaches that don't work:

  1. 90% fail

    Refs are null during initial render; the container must exist in the DOM before createPortal runs.

  2. 85% fail

    The element is not attached to the DOM, so it's not a valid container for a portal.

  3. 75% fail

    Timers are unreliable and may still run before the DOM is ready; also causes race conditions.