Как исправить ошибку React Portal: целевой контейнер не является элементом DOM

У меня проблема с работой реагирующих порталов. Я не понимаю, почему я получаю сообщение об ошибке. Идентификатор портала не является элементом DOM, который явно является допустимым элементом DOM.

У меня есть песочница здесь

Код целиком представлен здесь. В console.log правильно сообщается, что элемент является элементом DOM, но React выдает ошибку.

import "./styles.css";
import { createPortal } from "react-dom";
import { useEffect, useState } from "react";

export default function App() {
  const [portalDiv, setPortalDiv] = useState(undefined);

  useEffect(() => {
    let pd = document.getElementById("portalDiv");
    console.log(pd);
    setPortalDiv(pd);
  }, []);

  return (
    <>
      <div id="portalDiv">portal container</div>
      <div className="app">
        {/* {console.log("render portaldiv", portalDiv)} */}
        {
          (portalDiv &&
            createPortal(
              <>
                <h1>Inside portal</h1>
              </>
            ),
          portalDiv)
        }
        <h1>Outside portal</h1>
      </div>
    </>
  );
}

Любые советы приветствуются. Спасибо.

Ваш вариант использования не имеет смысла, зачем вам вводить в V-DOM? Портал предназначен для внедрения в DOM. «Порталы предоставляют первоклассный способ визуализации дочерних элементов в узле DOM, который существует вне иерархии DOM родительского компонента». Вы уверены, что действительно хотите это сделать? Если это так, используйте React API - useRef вместо запроса через объект документа - так что у вас не будет состояния гонки (вот что происходит в этом случае).

Dennis Vash 10.04.2022 13:21

Я предполагаю, что ваша ошибка заключается в понимании того, что означает «вне иерархии DOM родительского компонента», это означает вставку в элемент в вашем файле HTML, файл index.html, где находится ваш «<div id="root"></div>" расположен, он предназначен для внедрения в другой элемент, кроме этого корня.

Dennis Vash 10.04.2022 13:30
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
Приложение для отслеживания бюджета на React js для начинающих
Приложение для отслеживания бюджета на React js для начинающих
Обучение на практике - это проверенная тема для достижения успеха в любой области. Если вы знаете контекст фразы "Практика делает человека...
Стоит ли использовать React в 2022 году?
Стоит ли использовать React в 2022 году?
В 2022 году мы все слышим о трендах фронтенда (React, Vue), но мы не знаем, почему мы должны использовать эти фреймворки, когда их использовать, а...
Как передать состояние или данные в react-router v6
Как передать состояние или данные в react-router v6
react-router - это лучшая библиотека для работы с маршрутизацией в reactjs. С помощью react-router вы передаете состояние или данные от одного...
0
2
9
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Этот вариант использования не рекомендуется, как указано в моем комментарии, но вот воспроизводимый пример.

Если вы намереваетесь внедрить узел React в VDOM, вам следует использовать для этого React API, чтобы вы не столкнулись с состоянием гонки при запросе DOM через DOM API.

import "./styles.css";
import { createPortal } from "react-dom";
import { useRef } from "react";

export default function App() {
  const containerRef = useRef();

  return (
    <>
      <div ref={containerRef}>portal container</div>
      <div id="app">
        {containerRef.current &&
          createPortal(<h1>Example Element</h1>, containerRef.current)}
        <h1>Outside portal</h1>
      </div>
    </>
  );
}

Edit portal id is not a DOM element (forked)

Спасибо, я думаю, что ваш пример предлагает решение, но я не уверен, почему это работает, а мой пример - нет. Я эффективно делаю то же самое, используя функцию получения DOM вместо ссылки. ? Разве этот пример также не противоречит вашему предыдущему совету о внедрении в index.html вне корня компонента React? Я действительно пытаюсь понять, а не поймать тебя. Спасибо

Laurence Fass 10.04.2022 13:31

Попробуйте прочитать документы и понять цель React, зачем вам использовать функцию DOM, когда у вас есть React, вот что он пытается каким-то образом решить.

Dennis Vash 10.04.2022 13:33

Не стесняйтесь писать мне в директ в твиттере. Я чувствую, что есть пробел в понимании, поэтому потребуется много времени, чтобы заполнить его в комментариях.

Dennis Vash 10.04.2022 13:36

Большое спасибо, у меня нет учетной записи в Твиттере. У вас есть другое средство связи? Я до сих пор не понимаю, почему вы эффективно представили тот же пример, используя ссылку, и это работает, несмотря на то, что вы предлагаете, что этого не должно быть. #смущенный.

Laurence Fass 10.04.2022 13:37

Я не сказал, что это не должно работать, я сказал, что это не рекомендуемый вариант использования, и он не «эффективно делает то же самое», а на самом деле НЕ делает то же самое вообще.

Dennis Vash 10.04.2022 13:41

«Если вы собираетесь внедрить узел React в VDOM, вам следует использовать для этого React API, чтобы вы не столкнулись с состоянием гонки при запросе DOM через DOM API». - пропустил этот момент в первый раз. Думаю, это то, что я делал неправильно. большое спасибо Денис.

Laurence Fass 10.04.2022 13:46

Другие вопросы по теме