Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Portal inserting content multiple times

Created a React portal and it works well except that it renders the requested content into the portal twice.

enter image description here

It also seems to run the function that inserts the content many times:

enter image description here

import React from "react";
import ReactDOM from "react-dom";
import PropTypes from "prop-types";

export default function Portal({
  id
}) {
  console.log("Inserting into portal");
  return (
    <>
      {ReactDOM.createPortal(
        <div>MY REACT CONTENT</div>,
        window.document.getElementById(`portal-${id}`)
      )}
    </>
  );
}

ProductPrice.propTypes = {
  id: PropTypes.number.isRequired,
};

How can I structure this file to ensure that the portal is only created once?

like image 582
user1486133 Avatar asked Sep 13 '26 12:09

user1486133


1 Answers

I was surprised by this behavior and, given this github issue, I'm probably not the only one. The example given in React's docs does not seem to have this problem (see last example here), and they appear to sidestep it using refs and state.

import { useRef, useEffect, useState } from 'react';
import { createPortal } from 'react-dom';
import { createMapWidget, addPopupToMapWidget } from './map-widget.js';

export default function Map() {
  const containerRef = useRef(null);
  const mapRef = useRef(null);
  const [popupContainer, setPopupContainer] = useState(null);

  useEffect(() => {
    if (mapRef.current === null) {
      const map = createMapWidget(containerRef.current);
      mapRef.current = map;
      const popupDiv = addPopupToMapWidget(map);
      setPopupContainer(popupDiv);
    }
  }, []);

  return (
    <div style={{ width: 250, height: 250 }} ref={containerRef}>
      {popupContainer !== null && createPortal(
        <p>Hello from React!</p>,
        popupContainer
      )}
    </div>
  );
}
like image 147
huntzinger92 Avatar answered Sep 16 '26 10:09

huntzinger92