ReactJS - 門戶:在您的React應用程序中開啟新維度的入口

Hello, 動手學習React的開發者們!今天,我們將踏上一段令人興奮的旅程,探索React門戶的奇妙世界。想像一下,你正在建造一個房子(你的React應用程序),然後突然發現你需要一個秘密通道,將東西從一個房間傳送到另一個房間,而不必經過主走廊。這就是React門戶為您的組件所做的!

ReactJS - Portals

什麼是React門戶?

React門戶提供了一種一流的方法,將子組件渲染到存在於父組件DOM層次之外的一個DOM節點中。用更簡單的話來說,這就像創造一個蟲洞,讓您能夠在DOM樹的另一個地方渲染一個組件,即使它仍然是您的React組件層次的一部分。

我們為什麼需要門戶?

你可能會想,"我為什麼不能只是把我的組件渲染在我想要的地方?" 在大多數情況下,你可以!但有些情況下,門戶會派上用場:

  1. 模態對話框
  2. 工具提示
  3. 漂浮菜單
  4. 需要脫離容器的小工具

讓我們深入了解門戶是如何工作以及如何使用它們。

創建您的第一個門戶

要創建一個門戶,我們使用ReactDOM.createPortal()方法。這裡有一個基本示例:

import React from 'react';
import ReactDOM from 'react-dom';

function MyPortalComponent() {
return ReactDOM.createPortal(
<h1>我渲染在另一個地方!</h1>,
document.getElementById('portal-root')
);
}

在這個示例中,我們創建了一個門戶,將一個<h1>元素渲染到具有id 'portal-root'的DOM節點中。這個節點應該存在於您的HTML中,在您的主要React應用程序的根元素之外。

讓我們分解一下ReactDOM.createPortal()方法:

  1. 第一個參數是你想要渲染的React元素。
  2. 第二個參數是你想要渲染它的DOM元素。

真實世界的例子:模態對話框

讓我們創建一個更實用的例子 - 一個出現在應用程序內容頂部的模態對話框。

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

function Modal({ isOpen, onClose, children }) {
if (!isOpen) return null;

return ReactDOM.createPortal(
<div className="modal-overlay">
<div className="modal-content">
{children}
<button onClick={onClose}>關閉</button>
</div>
</div>,
document.getElementById('modal-root')
);
}

function App() {
const [isModalOpen, setIsModalOpen] = useState(false);

return (
<div>
<h1>歡迎來到我的應用程序</h1>
<button onClick={() => setIsModalOpen(true)}>打開模態</button>
<Modal isOpen={isModalOpen} onClose={() => setIsModalOpen(false)}>
<h2>這是一個模態</h2>
<p>它在主要React樹之外渲染!</p>
</Modal>
</div>
);
}

在這個例子中,我們創建了一個可重用的Modal組件,它使用門戶來渲染其內容。App組件使用React的useState hook控制模態的可见性。

讓我們分解一下發生了什麼:

  1. Modal組件檢查它是否應該打開(isOpen屬性)。
  2. 如果打開,它創建一個門戶來渲染其內容到'modal-root'元素。
  3. 模態內容包括一個關閉按鈕,它會觸發onClose屬性。
  4. App組件中,我們使用狀態來控制模態的可見性。

門戶中的事件冒泡

門戶的一個有趣方面是,即使它們可以將內容渲染到DOM樹中的任何地方,事件仍然會像預期的那樣在React樹中上冒泡。讓我們看一個例子:

import React, { useState } from 'react';
import ReactDOM from 'react-dom';

function Parent() {
const [clicks, setClicks] = useState(0);

const handleClick = () => {
setClicks(clicks + 1);
};

return (
<div onClick={handleClick}>
<h1>點擊次數:{clicks}</h1>
<Portal>
<Child />
</Portal>
</div>
);
}

function Portal({ children }) {
return ReactDOM.createPortal(
children,
document.getElementById('portal-root')
);
}

function Child() {
return <button>點我!</button>;
}

在這個例子中,點擊門戶內的按鈕仍然會觸發父組件中的點擊處理程序,增加點擊次數。這種行為非常有用,因為它保持了預期的事件傳播,無論組件實際在DOM中的渲染位置如何。

最佳實踐和考慮因素

使用門戶時,請記住以下幾點:

  1. 無障礙性:確保您的門戶內容對於屏幕閱讀器來說是可訪問的。
  2. 事件處理:記住事件在React樹中冒泡,而不是DOM樹。
  3. 樣式:門戶內容可能需要單獨的樣式考慮。
  4. 清理:不要忘記在組件卸載時清理您的門戶。

門戶方法

這裡是與React門戶相關關鍵方法的表格:

方法 描述
ReactDOM.createPortal(child, container) 創建一個門戶。child 是任何可渲染的React子元素,container 是一個DOM元素。
ReactDOM.unmountComponentAtNode(container) 從DOM中移除已挂载的React組件并清理其事件處理器和狀態。

結論

React門戶是一個强大的功能,它讓您能在渲染時脫離傳統的組件層次。它們特別適合創建模態對話框、工具提示和其他需要視覺上“脫離”容器的UI元素。

記住,能力越大,責任越大!謹慎使用門戶,並始終考慮它們對您應用程序結構和無障礙性的影響。

開心地編程,願你的門戶總是引領你走向React應用程序中的新維度!

Credits: Image by storyset