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. Confluence 6 SQL 异常的问题解决

    如果你得到了与下面显示内容类似的信息话,那么你最好考虑修改 Confluence 的日志级别输出更多的信息.如果你考虑通过 Atlassian support 获得帮助,那么这些详细的错误信息能够更好 ...

  2. 多版本python安装第三方库

    1.先进入对应版本的python 2.使用命令安装:./pip install xxx

  3. Jmeter3.0 中文乱码的解决方法

    在Body Data中输入中文时,发现是乱码,如下图 这种情况在jmeter3.0的版本中才会产生,由于3.0中优化body data后,使用默认的字体(Consolas)不支持汉字的显示. 解决方法 ...

  4. 用ffmpeg把视频编码格式转为h.264

    command: ffmpeg -i infile.mp4 -an -vcodec libx264 -crf 23 outfile.h264

  5. Sublime Text 3 快捷键总结(拿走)

    以下是个人总结不完全的快捷键总汇,祝愿各位顺利解放自己的鼠标. 选择类 Ctrl+D 选中光标所占的文本,继续操作则会选中下一个相同的文本. Alt+F3 选中文本按下快捷键,即可一次性选择全部的相同 ...

  6. requests之json系列(一)

    以post方式获取接口指定的相关信息 #! /usr/bin/env python # coding=utf-8 import json import urllib import requests i ...

  7. 磁盘修改AF

    请严格按照如下流程: 1 以管理员打开 硬盘安装助手 2 选择苹果Mac系统镜像 (cdr格式的) 3 直接选择要写入的盘,不要点击右边的方框中的勾选 (此时就可以写入了,虽然最后还是显示 Chang ...

  8. Go语言之函数签名

    使用type关键字进行, 函数类型变量也可以作为函数的参数或返回值. 我觉得属于高级技巧了,初学者可能需要很多代码实现的, 高级的就可以更通用的实现. package main import &quo ...

  9. DBEntityEntry类

    DBEntityEntry是一个重要的类,可用于检索有关实体的各种信息.您可以使用DBContext的Entry方法获取特定实体的DBEntityEntry实例. DBEntityEntry允许您访问 ...

  10. bzoj4773: 负环

    题解: 网上还有一种spfa+深度限制的算法 https://www.cnblogs.com/BearChild/p/6624302.html 是不加队列优化的spfa,我觉得复杂度上限是bellma ...