Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案

Portal 语法

/*
 * 参数:
 *  1. children:可以渲染的任何内容,如 JSX 片段、字符串或数字,以及这些内容构成的数组
 *  2. domNode:某个已经存在的 DOM 节点,在更新过程中传递不同的 DOM 节点将导致 portal 内容被重建
 *  3. key:用作 portal key 的独特字符串或数字
 * 返回值:该函数返回一个 React 元素
 */
ReactDOM.createPortal(children, domNode, key?);

Portal 案例

  1. 示例代码:

    HTML
    JavaScript
    JavaScript
    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="utf-8" />
        <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <title>React App</title>
        <style>
            .modal {
                position: fixed;
                left: 0;
                top: 20%;
                width: 100%;
                height: 80%;
                background: rgba(0, 0, 0, .5);
            }
        </style>
    </head>
    
    <body>
        <div id="root"></div>
        <div class="modal"></div>
    </body>
    
    </html>
    
    import React from "react";
    import ReactDOM from "react-dom";
    import App from "./App";
    
    ReactDOM.render(<App />, document.getElementById("root"));
    
    import React from "react";
    import ReactDOM from "react-dom";
    
    function ChildA() {
      return ReactDOM.createPortal(
        <div className="child-a" style={{ marginTop: 200 }}>
          <h1>ChildA</h1>
        </div>,
        document.querySelector(".modal")
      );
    }
    
    export default function App() {
      return (
        <div className="app">
          <h1>App</h1>
          <ChildA />
        </div>
      );
    }
    
  2. 效果展示

注意事件冒泡

  1. React 中的事件是包装过的,它的事件冒泡是根据虚拟 DOM 树来冒泡的,与真实的 DOM 树无关;

    import React from "react";
    import ReactDOM from "react-dom";
    
    function ChildA() {
      return ReactDOM.createPortal(
        <div className="child-a" style={{ marginTop: 200 }}>
          <h1>ChildA</h1>
          <ChildB />
        </div>,
        document.querySelector(".modal")
      );
    }
    
    function ChildB() {
      return (
        <div className="child-b">
          <h1>ChildB</h1>
        </div>
      );
    }
    
    export default function App() {
      return (
        <div
          className="app"
          onClick={(e) => {
            console.log("App被点击了", e.target);
          }}
        >
          <h1>App</h1>
          <ChildA />
        </div>
      );
    }
    
  2. 所以在点击 ChildA、ChildB 后会触发根节点的 click 点击事件;

打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. Portal 语法
  2. 2. Portal 案例
  3. 3. 注意事件冒泡