【问题标题】:React and using ReactDOM.createPortal() - Target container is not a DOM element Error反应并使用 ReactDOM.createPortal() - 目标容器不是 DOM 元素错误
【发布时间】:2019-07-06 17:25:01
【问题描述】:

我正在开发一个 React 应用程序,并尝试使用 ReactDOM.createPortal() 将 html 内容添加到组件(称为 ToDoItem)外部的 div。

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

公用文件夹中的所有 HTML 都不是预定义的 - 它都是动态创建的。

我认为这可能是错误的原因:React 尝试将 HTML 添加到 id 为 tasks 的 div 中,但在此之前 div 没有加载到 DOM 中?

如果此方法不正确,我可以使用其他方法将 html 内容附加到组件外的另一个 div 吗?

其他一些信息:我尝试运行此方法的组件是无状态组件,而不是类组件。

这是错误:

【问题讨论】:

    标签: javascript reactjs


    【解决方案1】:

    您可以使用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
    }
    

    【讨论】:

      【解决方案2】:

      在第一次渲染组件之前,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}
      

      【讨论】:

        【解决方案3】:

        我遇到了这个问题,因为我忘记在我的 index.html 文件中添加 &lt;div id="some-id"&gt;&lt;/div&gt; :-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>
        

        【讨论】:

          【解决方案4】:

          问题是你不能 createProtal 来响应组件。 第二个参数必须是 dom elemenet,而不是 react created element

          【讨论】:

            【解决方案5】:

            createPortal 的第一个参数应该是一个 dom 元素。您没有传递 dom 元素(您正在传递 Route 的实例)。

            【讨论】:

              猜你喜欢
              • 2017-11-24
              • 1970-01-01
              • 2022-10-09
              • 2023-03-15
              • 2021-06-17
              • 2014-12-12
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多