React一个比较好用的功能是其简单的API,一个组件可以简单到一个return了组件结构的render函数。除了一个简单的函数之外,我们还有了一段有用且可复用的代码片段。

问题

不过有时候可能会受到限制。

特别是,实际上这个API返回的是一个没有限制dom挂载在何处的组件,这就使得一些popup组件比较困难去实现。如果父元素限制了oerflow为hidden。就像下面这个例子一样



实际上我们想要的是这样的:

解决

幸运的是有一种相当优雅的方式来达到目的,尽管该方式并不太常见。

作为每个人最早学习到的React方法之一,React.render大概如下:

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组件里,像下面这样就行了:

var Dialog = React.createClass({
render: function() {
// 弹框组件
var dialogPopup = <DialogPopup {...this.props} />;
// 包括该组件
return (
<RenderInBody>{dialogPopup}</RenderInBody>
);
}
});

结束语

原文地址

Rendering React components to the document body

本文翻自Rendering React components to the document body这就是所谓的render to body模式.

对于那些popup即弹出层组件,如果将其直接挂载在父元素下面,可能会存在被父元素影响的可能。

为了解决这样的问题,作者提供了一种思路,既然可能会受直接父元素影响,那么直接跨过去,挂载到body上不就解决这个问题了。

这就是本文的用意所在。

感谢原作者,学习到了一种更优雅的处理方式,原本自己写的Dialog之类的组件,确实是挂到直接父元素下面,即写在哪出现在哪,很容易受到其他元素影响。

好文共赏,与诸君共勉。

Rendering React components to the document body的更多相关文章

  1. React Components之间的通信方式了解下

    先来几个术语: 官方 我的说法 对应代码 React element React元素 let element=<span>A爆了</span> Component 组件 cla ...

  2. [Poi] Use Markdown as React Components by Adding a Webpack Loader to Poi

    Poi ships with many webpack loaders included, but you may run into scenarios where you'll need to cu ...

  3. React components render order All In One

    React components render order All In One components render order / components lifecycle DOM tree ren ...

  4. [React] Styling React Components With Aphrodite

    Aphrodite is a library styling React components. You get all the benefits of inline styles (encapsul ...

  5. React Components Template

    React Components Template "use strict"; /** * * @author xgqfrms * @license MIT * @copyrigh ...

  6. [React] Create and import React components with Markdown using MDXC

    In this lesson I demonstrate how to use the library MDXC to create and import React components with ...

  7. [React] Recompose: Theme React Components Live with Context

    SASS Bootstrap allows us to configure theme or branding variables that affect all components (e.g. P ...

  8. [React] Intro to inline styles in React components

    React lets you use "inline styles" to style your components; inline styles in React are ju ...

  9. [React] Extracting Private React Components

    we leverage private components to break our render function into more manageable pieces without leak ...

随机推荐

  1. SELinux简介(转载)

    几乎可以肯定每个人都听说过 SELinux (更准确的说,尝试关闭过),甚至某些过往的经验让您对 SELinux 产生了偏见.不过随着日益增长的 0-day 安全漏洞,或许现在是时候去了解下这个在 L ...

  2. Android源码分析二 硬件抽象层(HAL)

    一 什么是HAL HAL 可定义一个标准接口以供硬件供应商实现,这可让 Android 忽略较低级别的驱动程序实现.借助 HAL,您可以顺利实现相关功能,而不会影响或更改更高级别的系统.HAL 实现会 ...

  3. BeautifulSoup的基本操作

    >>> from bs4 import BeautifulSoup   #导入 >>> soup = BeautifulSoup(url.content," ...

  4. thymleaf模板截取日期的年月日,去掉时分秒

    简单描述:浏览同事提交的代码,发现他的日期回显中有一行代码,只截取到了年月日,记录一下 代码: //HTML代码 <span th:text="${#strings.substring ...

  5. 从认识面向对象到构造函数的标准写法(构造函数的继承、多态、ECMA6中新代替语法class) - 下

    笔记一个包含:认识面向对象.构造函数的封装.继承.多态.ECMA6中新代替语法class 下:包括构造函数的继承.多态.ECMA6中新代替语法class 构造函数的继承 从父一级延续下来的属性和功能( ...

  6. bootstrap-table 刷新页面数据

    bom.bootstrapTable('load',msg['object']);//这一步 务必要添加. if(msg['code']==1){ bom.find('tbody').css('dis ...

  7. 跨域 jQuery库ajax请求

    XMLHttpRequest是原生ajax,缺点是使用起来比较繁琐. jQuery库提供了一组简洁的ajax请求方法. ajax() get() post() 具体使用参考官方API: http:// ...

  8. JavaMail在Windows平台下正常发送邮件,部署到Linux后则发送失败

    问题: 在本机(Windows)环境下可以成功发送邮件,但部署到Linux服务器上后不能成功发送,前台不提示错误或提示502. linux下日志提示:javamail isssl false.... ...

  9. 用C语言实现窗口抖动

    #include "stdafx.h" #include <stdio.h> #include<Windows.h> int main() { ; //休眠 ...

  10. .netcore读取配置文件

    setting.json { "compilerOptions": { "noImplicitAny": false, "noEmitOnError& ...