У меня проблема с работой реагирующих порталов. Я не понимаю, почему я получаю сообщение об ошибке. Идентификатор портала не является элементом 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>
</>
);
}
Любые советы приветствуются. Спасибо.
Я предполагаю, что ваша ошибка заключается в понимании того, что означает «вне иерархии DOM родительского компонента», это означает вставку в элемент в вашем файле HTML, файл index.html
, где находится ваш «<div id="root"></div>" расположен, он предназначен для внедрения в другой элемент, кроме этого корня.
Этот вариант использования не рекомендуется, как указано в моем комментарии, но вот воспроизводимый пример.
Если вы намереваетесь внедрить узел 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>
</>
);
}
Спасибо, я думаю, что ваш пример предлагает решение, но я не уверен, почему это работает, а мой пример - нет. Я эффективно делаю то же самое, используя функцию получения DOM вместо ссылки. ? Разве этот пример также не противоречит вашему предыдущему совету о внедрении в index.html вне корня компонента React? Я действительно пытаюсь понять, а не поймать тебя. Спасибо
Попробуйте прочитать документы и понять цель React, зачем вам использовать функцию DOM, когда у вас есть React, вот что он пытается каким-то образом решить.
Не стесняйтесь писать мне в директ в твиттере. Я чувствую, что есть пробел в понимании, поэтому потребуется много времени, чтобы заполнить его в комментариях.
Большое спасибо, у меня нет учетной записи в Твиттере. У вас есть другое средство связи? Я до сих пор не понимаю, почему вы эффективно представили тот же пример, используя ссылку, и это работает, несмотря на то, что вы предлагаете, что этого не должно быть. #смущенный.
Я не сказал, что это не должно работать, я сказал, что это не рекомендуемый вариант использования, и он не «эффективно делает то же самое», а на самом деле НЕ делает то же самое вообще.
«Если вы собираетесь внедрить узел React в VDOM, вам следует использовать для этого React API, чтобы вы не столкнулись с состоянием гонки при запросе DOM через DOM API». - пропустил этот момент в первый раз. Думаю, это то, что я делал неправильно. большое спасибо Денис.
Ваш вариант использования не имеет смысла, зачем вам вводить в V-DOM? Портал предназначен для внедрения в DOM. «Порталы предоставляют первоклассный способ визуализации дочерних элементов в узле DOM, который существует вне иерархии DOM родительского компонента». Вы уверены, что действительно хотите это сделать? Если это так, используйте React API - useRef вместо запроса через объект документа - так что у вас не будет состояния гонки (вот что происходит в этом случае).