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