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
廣告