ReactJS - createPortal() 方法



React portals 允许我们将网站的某些部分移动到屏幕上的不同位置。它们对于各种活动非常有用,例如显示弹出框或将内容插入页面的特定部分。

createPortal 是一个 React 函数,允许我们在网站上移动项目。假设我们在网站上有一个框,我们希望某些内容出现在该框内页面上的不同位置。这就是 createPortal 发挥作用的地方。

语法

<div>
   <MyComponent />
   {createPortal(children, domNode, key!)}
</div>

参数

  • children − 我们想要显示的任何内容,例如文本、图片或网站的另一个部分。

  • domNode − 我们希望内容出现在页面上的位置。它可以是整个页面或只是一部分。

  • 可选 key − 这是一段额外的代码,可以帮助 React 跟踪事物。这通常留空。

返回值

当我们使用 createPortal 时,我们会得到一个特殊的返回值。这个特殊对象类似于一张魔法卡,我们可以将其插入我们的代码中,React 将知道在哪里显示我们的内容。

示例

让我们通过创建小型 React 应用来查看 createPortal 的不同示例。

示例 1

此应用显示一个按钮。当我们单击按钮时,屏幕上会显示一个名为“模态”的特殊窗口。“模态”就像一个小盒子,包含一些信息或选项。我们可以通过单击其中的小“x”来关闭模态。

AppModal.js

import React from 'react';
import { createPortal } from 'react-dom';

const AppModal = ({ isOpen, onClose }) => {
   const modalRoot = document.getElementById('modal-root');   
   if (!modalRoot) {
      console.error("Modal root container not found in the DOM.");
      return null;
   }   
   return isOpen ? createPortal(
      <div className="modal App">
         <div className="modal-content">
            <span className="close" onClick={onClose}>×</span>
            <p>This is a modal!</p>
         </div>
      </div>,
      modalRoot
   ) : null;
};

export default AppModal;

index.html

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="utf-8" />
   <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
   <meta name="viewport" content="width=device-width, initial-scale=1" />
   <meta name="theme-color" content="#000000" />
   <meta
   name="description"
   content="Web site created using create-react-app"
   />
   <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
   <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
   <title>React App</title>
</head>
<body>
   <div id="root"></div>
   <div id="modal-root"></div>
</body>
</html>

App.js

import React, { useState } from 'react';
import AppModal from './AppModal';
import './App.css';

const App = () => {
   const [modalOpen, setModalOpen] = useState(false);   
   const handleOpenModal = () => setModalOpen(true);
   const handleCloseModal = () => setModalOpen(false);   
   return (
      <div className='App'>
         <h1>Modal</h1>
         <button onClick={handleOpenModal}>Open Modal</button>
         <AppModal isOpen={modalOpen} onClose={handleCloseModal} />
      </div>
   );
};

export default App;

输出

open modal

有一个名为“打开模态”的按钮。当我们单击按钮时,会出现一个带有消息的模态。要关闭模态,我们可以单击左侧的“x”。

示例 2

此应用有一个按钮,当我们将鼠标悬停在按钮上时,会出现一个小框,其中包含额外信息。这个小框称为“工具提示”。它为我们提供了有关按钮的更多详细信息。

AppTooltip.js

import React from 'react';
import { createPortal } from 'react-dom';
import './App.css';

const AppTooltip = () => {
   const tooltipRoot = document.getElementById('tooltip-root');   
   if (!tooltipRoot) {
      console.error("Tooltip root container not found in the DOM.");
      return null;
   }   
   return createPortal(
      <div className="tooltip App">
         <p>This is a tooltip!</p>
      </div>,
      tooltipRoot
   );
};

export default AppTooltip;

index.html

<!DOCTYPE html>
<html lang="en">
<head>
   <title>React App</title>
</head>
<body>
   <div id="root"></div>
   <div id="tooltip-root"></div>
</body>
</html>

App.js

import React from 'react';
import AppTooltip from './AppTooltip';
import './App.css';

const App = () => {
   return (
      <div className='App'>
         <h1>Tooltip App</h1>
         <button>Hover me</button>
         <AppTooltip />
      </div>
   );
};

export default App;

输出

tooltip app

有一个按钮,我们可以将鼠标悬停在其上。当我们将鼠标悬停在按钮上时,会出现一个小方框,其中包含信息。这个方框是工具提示,当我们移开鼠标时它会消失。

示例 3

在这个应用中,有一个特殊的组件似乎漂浮在页面上。它就像一个小方框,其中包含信息,即使我们滚动页面,它也保持在一个位置。这对于我们希望人们始终看到的重要细节很有用。

AppFloatingComponent.js

import React from 'react';
import { createPortal } from 'react-dom';

const AppFloatingComponent = () => {
   const floatingRoot =    document.getElementById('floating-root');   
   return createPortal(
      <div className="floating-component">
         <p>This is a floating component!</p>
      </div>,
      floatingRoot
   );
};

export default AppFloatingComponent;

index.html

<div id="floating-root"></div>

App.js

import React from 'react';
import AppFloatingComponent from './AppFloatingComponent';
import './App.css';

const App = () => {
   return (
      <div className='App'>
         <h1>Floating Component</h1>
         <AppFloatingComponent />
      </div>
   );
};

export default App;

输出

floating component

有一个包含信息的方框,它保持在页面上的一个位置。即使我们向上或向下滚动,该方框仍然可见。

这对于显示我们希望人们始终看到的重要信息非常方便。

限制

使用 portals 时,事件(例如单击)可能会以不同的方式发生。如果我们发现问题,我们可以从 portal 内部解决它们,或者重新定位网页家族中的 portal。

总结

React portals 就像神奇的门,让我们能够更好地构建网站。使用 createPortal,我们可以重新排列元素,使我们的网站看起来完全符合我们的预期。

reactjs_reference_api.htm
广告