2017-09-24 156 views
10

我正在使用React 16並需要門戶,但無法找到有關此功能的任何文檔。有誰知道如何使用這個呢?如何在React 16中使用ReactDOM.createPortal()?

https://github.com/facebook/react/pull/10675

感謝您的任何意見。

+1

https://facebook.github.io/react/docs/portals.html –

+1

該文檔非常清晰地解釋瞭如何使用它們......您是否閱讀過它們? – ndugger

+0

@ndugger是的,文檔現在已經足夠了:)。但OP在2天前提出了這個問題。然後React v16沒有發佈。它今天發佈,文檔也在今天發佈。 –

回答

14

React v16剛剛發佈幾個小時前(Yay !!),它正式支持Portal

什麼是Portal?因爲它在那裏有多久了?

門戶網站提供了一種一流的方式來將孩子呈現到存在於父組件的DOM層次結構之外的DOM節點。

Portal在反應社區中不是新概念。許多庫都支持這種功能。例如react-portalreact-gateway

渲染任何反應應用程序時會發生什麼?

通常,渲染任何React應用程序時,使用單個DOM元素來渲染整個React樹。

class HelloReact extends React.Component { 
    render() { 
     return (
      <h1>Hello React</h1> 
     ); 
    } 
} 

ReactDOM.render(<HelloReact />, document.getElementById('root')); 

正如你可以看到,我們正在呈現我們的反應組分到具有ID root DOM元素。

什麼是門戶網站,它爲什麼需要?爲什麼在那裏?

門戶是渲染方式作出反應父組件的主要DOM層次結構外部的孩子又不失反應方面。我強調這一點,因爲像react-router,redux這樣的非常受歡迎的庫大量使用反應環境。因此使用Portal時的上下文可用性非常有用。

由於每react文檔,

一個典型的用例門戶是當父組件具有溢出:隱藏或z-index的風格,但你需要的是兒童在視覺上的「突圍」它的容器。例如,對話框,懸浮卡片和工具提示。

因此,通過門戶,您可以在需要時將並行反應樹渲染到另一個DOM節點上。即使它在不同的DOM節點中呈現,父組件也可以捕獲未捕獲的事件。請參閱文檔本身提供的codepen

下面的例子應該給你更多的想法:

// index.html 
<html> 
    <body> 
     <div id="root"></div> 
     <div id="another-root"></div> 
    </body> 
</html> 

// index.jsx 
const mainContainer = document.getElementById('root'); 
const portalContainer = document.getElementById('another-root'); 

class HelloFromPortal extends React.Component { 
    render() { 
     return (
      <h1>I am rendered through a Portal.</h1> 
     ); 
    } 
} 

class HelloReact extends React.Component { 
    render() { 
     return (
      <div> 
       <h1>Hello World</h1> 
       { ReactDOM.createPortal(<HelloFromPortal />, portalContainer) } 
      </div> 
     ); 
    } 
} 

ReactDOM.render(<HelloReact />, mainContainer); 

https://codesandbox.io/s/62rvxkonnw

您可以使用devtools檢查元素,看到<h1>I am rendered through a Portal.</h1>在裏面#another-root標籤渲染,而<h1>Hello World</h1>在裏面#root標籤渲染。

希望這有助於:)

更新:要回答@PhillipMunin's comment

ReactDOM.renderReactDOM.createPortal之間有什麼不同?

  1. 即使通過門戶網站提供的部件呈現其他地方(外當前容器根),但它仍然存在相同的父組件的孩子。 (誰調用了ReactDOM.createPortal)因此,該孩子的任何事件都會傳播給父母。 (Ofc,如果您手動停止事件傳播,則這不起作用。)

  2. 在通過門戶呈現的組件內部可訪問相同的上下文。但不是在直接執行ReactDOM.render的情況下。

我創建了另一個演示來說明我的觀點。 https://codesandbox.io/s/42x771ykwx

+2

與編寫'{ReactDOM.render(,portalContainer)}'而不是'{ReactDOM.createPortal(...)}'有什麼不同?我在codesandbox中測試了它 - 似乎沒有任何不同:https://codesandbox.io/s/88p7lwn3l –

+0

@PhilippMunin除了保存在門戶中的上下文之外,事件還會傳播開來。嘗試在''的最上面的div中添加一個點擊監聽器,並且看到從<使用'render'點擊時不會傳播。當使用'createPortal'時,從門戶內部的點擊傳播到父組件。 – lyosef

+0

ReactDOM.unstable_renderSubtreeIntoContainer代替渲染怎麼樣?它應該通過的背景下,不知道事件 –

0

通過調用組件的render方法中的createPortal方法創建門戶。

render() { 
    return (
    <div> 
     {ReactDOM.createPortal(this.renderPortal(), this.props.portalEl)} 
    </div> 
) 
} 

renderPortal應返回門戶內要呈現的內容,而portalEl是將接收內容的外部DOM元素。

最近有人提供了關於門戶網站的信息,可以在React tests找到。

相關問題