React一個比較好用的功能是其簡單的API,一個組件能夠簡單到一個return了組件結構的render函數。除了一個簡單的函數以外,咱們還有了一段有用且可複用的代碼片斷。react
不過有時候可能會受到限制。
特別是,實際上這個API返回的是一個沒有限制dom掛載在何處的組件,這就使得一些popup組件比較困難去實現。若是父元素限制了oerflow爲hidden。就像下面這個例子同樣
實際上咱們想要的是這樣的:
app
幸運的是有一種至關優雅的方式來達到目的,儘管該方式並不太常見。
做爲每一個人最先學習到的React方法之一,React.render大概以下:dom
ReactComponent render( ReactElement element, DOMElement container, [function callback] )
一般咱們使用其來將整個應用掛載到一個DOM元素下面。使人愉悅的是,其不單單侷限於此,實際上咱們能夠在一個組件中經過React.render將另外一個組件掛載到徹底不一樣的DOM節點。做爲組件的render函數其自己必須保持純淨(不能改變state或者和dom進行交互) ,不然的話咱們應該在componentDidUpdate或者componentDidMount裏面進行操做。另外咱們須要確保當其父組件卸載的時,全部已經被渲染的組件能夠一樣正確的被卸載。函數
兼顧以上幾點,咱們能夠構建一個解決相關問題的組件。學習
/** * 注:該文章較早,與dom相關的方法已經被拆分到ReactDom中 */ var RenderInBody = React.createClass({ componentDidMount: function() { // 建立待彈出元素的掛載節點 this.popup = document.createElement("div"); // 添加至document.body document.body.appendChild(this.popup); this._renderLayer(); }, componentDidUpdate: function() { // 更新時 this._renderLayer(); }, componentWillUnmount: function() { // 從掛載節點上清除popup元素 // (React元素使用該方法,清除的不只是dom還有state和事件) React.unmountComponentAtNode(this.popup); // 移除掛載節點 document.body.removeChild(this.popup); }, _renderLayer: function() { // 將children掛載到 popup節點 React.render(this.props.children, this.popup); } render: function() { // 渲染一個佔位符。 return React.DOM.div(this.props); } });
而後不管什麼時候咱們想要將父組件的dom轉換到document.body上時,須要作的只是將咱們組件的輸出包括在RenderInBody組件裏,像下面這樣就好了:this
var Dialog = React.createClass({ render: function() { // 彈框組件 var dialogPopup = <DialogPopup {...this.props} />; // 包括該組件 return ( <RenderInBody>{dialogPopup}</RenderInBody> ); } });
Rendering React components to the document bodycode
本文翻自Rendering React components to the document body這就是所謂的render to body模式.
對於那些popup即彈出層組件,若是將其直接掛載在父元素下面,可能會存在被父元素影響的可能。
爲了解決這樣的問題,做者提供了一種思路,既然可能會受直接父元素影響,那麼直接跨過去,掛載到body上不就解決這個問題了。
這就是本文的用意所在。
感謝原做者,學習到了一種更優雅的處理方式,本來本身寫的Dialog之類的組件,確實是掛到直接父元素下面,即寫在哪出如今哪,很容易受到其餘元素影響。
好文共賞,與諸君共勉。component