Search code examples
javascriptreactjsreact-hooksreact-portal

ReactDOM.createPortal() renders empty element when called in a function


I have a simple React.js app that tries to render content in a Portal on a callback, does someone have any ideas why it isn't rendering anything?

Runnable CodeSandbox

import React from 'react'
import ReactDOM from 'react-dom'
import './App.css';

function App() {
  const showElement = React.useCallback(() => {
    const element = document.createElement('div');
    document.querySelector('body').appendChild(element)
    ReactDOM.createPortal(() => <div>TEST</div>, element)
  }, [])
  
  return (
    <div className="App">
      <button onClick={showElement}>Click to Render Portal</button>
    </div>
  );
}

export default App;

Solution

  • You aren't returning the created portal in the return of the App component, so it's not actually being rendered.

    Try something more like:

    function App() {
      const elementRef = useRef(document.createElement("div"));
    
      const showElement = React.useCallback(() => {
        document.querySelector("body").appendChild(elementRef.current);
      }, []);
    
      return (
        <div className="App">
          <button onClick={showElement}>Click to Render Portal</button>
          {ReactDOM.createPortal(<div>TEST</div>, elementRef.current)}
        </div>
      );
    }
    

    This creates a React ref to hold the created DOM element, renders the portal with the return of the component JSX, and appends the DOMNode in the button's onClick handler.

    Edit reactdom-createportal-renders-empty-element-when-called-in-a-function