当前位置:首页 > 日记 > 正文

React如何将组件渲染到指定DOM节点详解

React如何将组件渲染到指定DOM节点详解

前言

众所周知React优点之一就是他的API特别简单。通过render 方法返回一个组件的基本结构,如同一个简单的函数,就可以得到一个可以复用的react组件。但是有时候还是会有些限制的,尤其是他的API中,不能控制组件所应该渲染到的DOM节点,这就让一些弹层组件很难控制。当父元素设置为overflow:hidden 的时候,问题就会出现了。

例如就像下面的这样:

我们实际期待的效果是这样的:

幸运的是,虽然不是很明显,但有一个相当优雅的方式来绕过这个问题。我们学到的第一个react函数是render 方法,他的函数签名是这样的:

ReactComponent render( ReactElement element, DOMElement container, [function callback])

通常情况下我们使用该方法将整个应用渲染到一个DOM节点中。好消息是该方法并不仅仅局限于此。我们可以在一个组件中,使用ReactDom.render 方法将另一个组件渲染到一个指定的DOM 元素中。作为一个组件的render 方法,其必须是纯净的(例如:不能改变state或者与DOM交互).所以我们需要在componentDidUpdate 或者 componentDidMount 中调用ReactDom.render 方法。

另外我们需要确保在父元素被卸载的时候,改组件也要被卸载掉.

整理下,我们得到下面的一个组件:

import React,{Component} from 'react';import ReactDom from 'react-dom';export default class RenderInBody extends Component{ constructor(p){  super(); } componentDidMount(){//新建一个div标签并塞进body  this.popup = document.createElement("div");  document.body.appendChild(this.popup);  this._renderLayer(); } componentDidUpdate() {  this._renderLayer(); } componentWillUnmount(){//在组件卸载的时候,保证弹层也被卸载掉  ReactDom.unmountComponentAtNode(this.popup);  document.body.removeChild(this.popup); } _renderLayer(){//将弹层渲染到body下的div标签  ReactDom.render(this.props.children, this.popup); } render(){  return null; }}

总结下就是:

在componentDidMount的时候手动向body内塞一个div标签,然后使用ReactDom.render 将组件渲染到这个div标签

当我们想把组件直接渲染到body上的时候,只需要在该组件的外面包一层RenderInBody 就可以了.

export default class Dialog extends Component{ render(){  return {   <RenderInBody>i am a dialog render to body</RenderInBody>  } }}

译者增加:

将以上组件改造一下,我们就可以向指定的dom节点中渲染和卸载组件,并加上位置控制,如下:

//此组件用于在body内渲染弹层import React,{Component} from 'react'import ReactDom from 'react-dom';export default class RenderInBody extends Component{ constructor(p){  super(p); } componentDidMount(){  /**  popupInfo={   rootDom:***,//接收弹层组件的DOM节点,如document.body   left:***,//相对位置   top:***//位置信息  }  */  let {popupInfo} = this.props;   this.popup = document.createElement('div');  this.rootDom = popupInfo.rootDom;    this.rootDom.appendChild(this.popup);  //we can setAttribute of the div only in this way  this.popup.style.position='absolute';  this.popup.style.left=popupInfo.left+'px';  this.popup.style.top=popupInfo.top+'px';  this._renderLayer() } componentDidUpdate() {  this._renderLayer(); } componentWillUnmount(){  this.rootDom.removeChild(this.popup); } _renderLayer(){  ReactDom.render(this.props.children, this.popup); } render(){  return null; }}

注:位置获取和根结点判断函数

export default (dom,classFilters)=> { let left = dom.offsetLeft,  top = dom.offsetTop + dom.scrollTop,  current = dom.offsetParent,  rootDom = accessBodyElement(dom);//默认是body while (current !=null ) {  left += current.offsetLeft;  top += current.offsetTop;  current = current.offsetParent;  if (current && current.matches(classFilters)) {   rootDom = current;   break;  } } return { left: left, top: top ,rootDom:rootDom};}/***1. dom:为响应弹层的dom节点,或者到该dom的位置后,可以做位置的微调,让弹层位置更佳合适*2. classFilters:需要接收弹层组件的DOM节点的筛选类名/

原文地址

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。

相关文章

javascript实现table单元格点击展

javascript实现table单元格点击展

实例代码,单元格,效果,电脑软件,javascript,如果table元素的高如果不设置,是根据内容撑开的,根据这个规则,可以用js控制默认状态下table-cell的宽度,并将这一列的table-cell设置为dispaly:block,这样多出来的内容就会被隐藏掉,添加点击事件,把table…

JavaScript之DOM_动力节点Java学院

JavaScript之DOM_动力节点Java学院

学院,节点,动力,电脑软件,JavaScript,由于HTML文档被浏览器解析后就是一棵DOM树,要改变HTML的结构,就需要通过JavaScript来操作DOM。始终记住DOM是一个树形结构。操作一个DOM节点实际上就是这么几个操作:更新:更新该DOM节点的内容,相当于更新了…

Yii2.0中使用js异步删除示例

Yii2.0中使用js异步删除示例

删除,异步,示例,电脑软件,js,整理文档,搜刮出一个Yii2.0中使用js异步删除示例,稍微整理精简一下做下分享。控制器:public function actionWeixinnotificationdel(){ $model = WxDistributorNotification::findOne($_GET['id']); if ($model)…

Excel中2010进行自动填充数据的操

Excel中2010进行自动填充数据的操

自动填充,数据,操作技巧,操作步骤,电脑软件,  序列填充是Excel中提供的最常用的快速输入技术之一。在Excel中可以通过以下途径进行数据的自动填充。今天,小编就教大家在Excel中2010进行自动填充数据的操作技巧。Excel中2010进行自动填充数…

JS实现页面打印功能

JS实现页面打印功能

页面,功能,电脑软件,JS,打印整个页面示例1.可直接在按钮添加调用打印方法:<input type='button' value='打印整页' onclick='javascript:window.print();' />示例2.也可调用JS方法<html><head><script type="text/javascript">funct…

ES6解构赋值实例详解

ES6解构赋值实例详解

赋值,详解,实例,电脑软件,本文实例讲述了ES6解构赋值。分享给大家供大家参考,具体如下:基本用法let [x, y, ...z] = ['a']//"a", undefined, []1.等号右边如果不是数组,将会报错(不是可遍历结构)2.解构赋值 var, let, const命令声明均适用3.…

关于vue.js发布后路径引用的问题解

关于vue.js发布后路径引用的问题解

引用,路径,电脑软件,vue,js,本文主要给大家介绍了关于vue.js发布后路径引用问题的解决方法,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍:在发布到iis目录下时候,如果放在网站的根目录下的时候,是不会有什么问题的但是一旦放在了…

import与export在node.js中的使用

import与export在node.js中的使用

详解,电脑软件,export,import,js,简述import与export是es6中模块化的导入与导出,node.js现阶段不支持,需要通过babel进行编译,使其变成node.js的模块化代码。(关于node.js模块,可参考其他node.js模块化的文章)export 曝露使用export可以曝露出方…

ppt2010电脑版怎么安装动画大师

ppt2010电脑版怎么安装动画大师

动画,安装,步骤,大师,电脑软件,  为了方便我们在ppt中对动画的制作,我们可以在ppt中安装动画大师,那么,你知道怎样在ppt中安装动画大师吗?下面就让小编告诉你 如何在ppt中安装动画大师的方法,希望看完本教程的朋友都能学会并运用起来。在ppt…

在PPT2007中怎么对多个对象同时执

在PPT2007中怎么对多个对象同时执

对象,执行,多个,动作,中对,  在制作PPT演示文稿中,经常会需要对一张幻灯片中的多个对象同时执行一个动作,那么怎么在PPT2007中实现这一功能呢?以下是小编为您带来的关于在PPT2007中对多个对象同时执行一个动作,希望对您有所帮助。在PPT2007…

关于php 高并发解决的一点思路

关于php 高并发解决的一点思路

高并发,思路,电脑软件,php,我的思路如下(伪代码):sql1:查询商品库存if(库存数量 > 0){//生成订单...sql2:同时库存-1}当没有并发时,上面的流程看起来是再正常不过了,假设同时两个人下单,而库存只有1个了,在sql1阶段两个人查询到的库存都是>0的,于…

Javascript调试之console对象——

Javascript调试之console对象——

调试,对象,你不知道,小技巧,电脑软件,前言写过前端Javascript代码的同学肯定不会对console对象感到陌生,在调试的过程中我们经常会用console对象在控制台输出一些常量或者变量。但是相信很多人也就只用过console.log()这一个方法,今天我们就…