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 5.3 及其早期版本中恢复空间

    如果你需要从 Confluence 5.3 及其早期版本中的导出文件恢复到晚于 Confluence 5.3 的 Confluence 中的话.你可以使用临时的 Confluence 空间安装,然后将 ...

  2. kafka架构浅显理解

    Kafka的概念: 1. AMQP协议 Advanced Message Queuing Protocol (高级消息队列协议) The Advanced Message Queuing Protoc ...

  3. 最小标示法模板 poj1509

    最小标示法:给定一个字符串,不断将其最后一个字符放到开头,最终会得到n个字符串,称这n个字符串循环同构,这些字符串中字典序最小的一个,就是最小表示法 #include<iostream> ...

  4. cf1025c 思维题

    /* bwwwbwwbw wwbwwwbwb 不管从哪里断开翻转.翻转后的串再整体翻转一定是2s的子串 */ #include<bits/stdc++.h> using namespace ...

  5. cf1108E2 线段树类似扫描线

    /* 有点像扫描线 思路:从左到右枚举每个点,枚举到点i时,把所有以i为起点的区间的影响删去 再加上以i-1为结尾的区间的影响 */ #include<bits/stdc++.h> usi ...

  6. 浏览器URL中 encodeURIComponent()加密和decodeURIComponent()解码

    encodeURIComponent()加密 定义和用法 encodeURIComponent() 函数可把字符串作为 URI 组件进行编码. 语法 encodeURIComponent(URIstr ...

  7. Python属性(@property)

    创建用于计算机的属性 在Python中,可以通过@property(装饰器)将一个方法转换为属性,从而实现用于计算的属性.将方法转换为属性后,可以直接通过方法名来访问方法,而不需要再添加一对小括号&q ...

  8. ruby安装sass和compass步骤

    依赖ruby,所以需要安装Ruby 如何安装Ruby呢?在windows下通过RubyInstaller来安装,安装过程中需要选择第二项 1.ruby -v 2.gem install sass (如 ...

  9. C++ 内链接 外链接

    编译的时候(假如编译器是VS),是以源文件cpp文件为单位,编译成一个个的obj文件,然后再通过链接器把不同的obj文件链接起来.如果一些变量或函数的定义是内连接的话,链接器链接的时候就不会拿它们去与 ...

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

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