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組件裏,像下面這樣就好了:ui
var Dialog = React.createClass({
render: function() {
// 彈框組件
var dialogPopup = <DialogPopup {...this.props} />; // 包括該組件 return ( <RenderInBody>{dialogPopup}</RenderInBody> ); } }); 複製代碼
Rendering React components to the document bodythis
本文翻自Rendering React components to the document body這就是所謂的render to body模式.
對於那些popup即彈出層組件,若是將其直接掛載在父元素下面,可能會存在被父元素影響的可能。
爲了解決這樣的問題,做者提供了一種思路,既然可能會受直接父元素影響,那麼直接跨過去,掛載到body上不就解決這個問題了。 這就是本文的用意所在。
感謝原做者,學習到了一種更優雅的處理方式,本來本身寫的Dialog之類的組件,確實是掛到直接父元素下面,即寫在哪出如今哪,很容易受到其餘元素影響。
好文共賞,與諸君共勉。spa