【问题标题】:Use React Portals within the React-App (not outside the DOM)在 React-App 内(不在 DOM 外)使用 React Portal
【发布时间】:2019-11-15 14:14:26
【问题描述】:

我想在我的 React 应用中实现模式。门户网站似乎对此非常好,但我不想更改我的外部 HTML 结构。

HTML-应该仍然是:

<div id="app"></div>

我不想在 HTML 结构中添加额外的 div。

在 App.js 中,我尝试像这样添加 root-modal-container:

class App extends Component {

  render() {
    return (
      <ResponsiveProvider>
        <div id="root-modal"></div>
        <Modal>
           <div>Modal :-)</div>
        </Modal>
      </ResponsiveProvider>
    );
  }
}

但是当尝试在模态组件中 getElementById 时,我总是得到错误:appendChild on null...

问题是,在启动 Modal-component 时,root-modal-div 没有渲染结束。

有什么解决方案可以让我在应用程序的任何位置之后直接在关卡中渲染模态框?

您可以看到未运行代码here。取消注释 HTML 中的第二行以使代码运行。

【问题讨论】:

  • 请分享所有必需的代码以重现您想要实现的目标
  • @Phillip 你可以在这里看到它:codepen.io/anon/pen/MMBdJW

标签: javascript reactjs


【解决方案1】:

您可以使用 React 门户来做到这一点,但这有点尴尬,并且您必须完全参与 DOM 本身才能在这样的应用程序中呈现(而不是完全外部的 DOM 节点)。

我刚刚发布了一个库来解决这个确切的问题,因为虽然门户网站可以解决这个问题,但这并不容易。

您可以在https://github.com/httptoolkit/react-reverse-portal查看完整的详细信息。

在您的示例中,解决方案类似于:

import React from "react";
import ReactDOM from "react-dom";
import * as portals from "react-reverse-portal";

class App extends React.Component {
  constructor(props) {
    super(props);
    // Create a portal node: the link between the two ends of the portal
    this.modalNode = portals.createPortalNode();
  }

  render() {
    // Place an OutPortal somewhere: this is where the content will appear.
    // Could be many levels deep in your app - you just need to get the modalNode
    // there. For complex cases you might want to put it in a context to distribute it.
    return <div>
      <Child modalNode={this.modalNode} />
      <portals.OutPortal node={this.modalNode} />
    </div>;
  }
}

const Child = props => {
  // Place an InPortal somewhere: this is where the content is defined
  return <portals.InPortal node={props.modalNode}>
    <Modal>
      <div>Modal :-)</div>
    </Modal>
  </portals.InPortal>
};

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

在上面:Child 定义了它想要出现的一些模态内容,App 定义了模态内容应该出现的空间。您可以使用它来链接应用程序的各个部分,并在它们之间发送渲染的内容。希望对您有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-04
    • 2019-12-09
    • 1970-01-01
    • 1970-01-01
    • 2020-12-22
    • 2022-01-24
    • 2021-08-05
    • 1970-01-01
    相关资源
    最近更新 更多