簡體   English   中英

反應並使用 ReactDOM.createPortal() - 目標容器不是 DOM 元素錯誤

[英]React and using ReactDOM.createPortal() - Target container is not a DOM element Error

我正在開發 React 應用程序,並嘗試使用ReactDOM.createPortal()將 html 內容添加到組件外部的 div(稱為 ToDoItem)。

{ReactDOM.createPortal(
    <Route path={`/profile/project/${this.props.project._id}`} render={() => 
    <ProjectView project={this.props.project}/>}  />,
    document.getElementById('tasks')
)}

公共文件夾中的 HTML 都不是預定義的 - 它都是動態創建的。

我認為這可能是錯誤的原因:React 嘗試將 HTML 添加到具有tasks ID 的 div,但在此之前 div 未加載到 DOM 中?

如果這個方法不對,有沒有其他方法可以用append html內容到組件外的另一個div?

其他一些信息:我嘗試從中運行此方法的組件是無狀態組件,而不是 class 組件。

這是錯誤:

在此處輸入圖像描述

在第一次渲染組件之前, DOM沒有元素,並且document.getElementById無法訪問任何元素。 第一次渲染后添加到DOM元素。

在父組件中使用useRef並將其發送到Portal Component

在父組件中:

const tasksRef = React.useRef(null);
const [tasksSt, setTasksSt]= React.useState();

....
    <div  ref={
        (current) => {tasksRef.current = current;
                setTasksSt(tasksRef.current);
                }
            }/>
    <YourPortalComp tasksRef={tasksRef} /> 
              

在門戶組件中

{this.props.tasksRef.current?(ReactDom.createPortal(<...>, this.props.tasksRef.current):null}

您可以使用React.useEffect等待 DOM 准備就緒,然后調用ReactDOM.createPortal

function Component() { 
  const [domReady, setDomReady] = React.useState(false)

  React.useEffect(() => {
    setDomReady(true)
  })

  return domReady 
    ? ReactDOM.createPortal(<div>Your Component</div>, document.getElementById('container-id')) 
    : null
}

如果加載了目標元素(在您的情況下帶有 id tasks的元素)但您仍然收到Target container is not a DOM element Error錯誤,您可以嘗試以下解決方案。

 const MyElement = () => { const [containerToLoad, setContainerToLoad] = useState(null); // If the target element is ready and loaded // set the target element useEffect(() => { setContainerToLoad(document.getElementById('container')); }, []); return containerToLoad && createPortal(<div>modal content</div>, containerToLoad); };

問題是你不能 createProtal 來反應組件。 第二個參數必須是dom元素,而不是反應創建的元素

我遇到了這個問題,因為我忘記將<div id="some-id"></div>到我的 index.html 文件中:-D

因此,提醒任何有類似問題或不知道如何使用 React 門戶(例如創建模態)的人:

modal.jsx 中

const modalRoot = document.getElementById('modal');

const Modal = () => {
  const modalElement = document.createElement('div');

  // appends the modal to portal once modal's children are mounted and 
  // removes it once we don't need it in the DOM anymore:
  useEffect(() => {
    modalRoot.appendChild(modalElement);
    return () => {
      modalRoot.removeChild(modalElement);
    };
  }, [modalElement]);

  return createPortal(<div>modal content</div>, modalRoot);
};

index.html 中

<!DOCTYPE html>
<html lang="en">
  <head>
    // head content
  </head>
  <body>
    <div id="root"></div>
    // dont't forget about this:
    <div id="modal"></div>
  </body>
</html>

在 index.html 文件中檢查你的 id,所以可以說,你的 index.html 文件有: <div id="overlays"></div>

你的模式應該指向同一個 div,即

const portalElement = document.getElementById('overlays');
const Modal = (props) => {
return (
    <Fragment>
      {ReactDOM.createPortal(<Backdrop onClose={props.onClose} />, portalElement)}
  </Fragment>
 );

};

對於那些可能使用 Next.js 的人,可以在此處找到與 AlexxBoro 對 next.js 的回答等價的內容。 https://www.learnbestcoding.com/post/101/how-to-create-a-portal-in-next.js

createPortal 的第一個參數應該是一個 dom 元素。 您沒有傳遞 dom 元素(您傳遞的是 Route 的實例)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM