全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

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节点的筛选类名
/

原文地址

总结

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


# reactjs  # 获取组件dom  # react  # 获取dom节点  # 重新渲染组件  # React组件通信之路由传参(react-router-dom)  # react四种组件中DOM样式设置方式详解  # 详解React获取DOM和获取组件实例的方式  # 就可以  # 是这样  # 的是  # 就会  # 就像  # 第一个  # 尤其是  # 很难  # 也要  # 卸载掉  # 只需  # 这个问题  # 要在  # 我们可以  # 这就  # 作为一个  # 当我们  # 这篇文章  # 想把  # 谢谢大家 


相关文章: 如何快速搭建高效香港服务器网站?  javascript中对象的定义、使用以及对象和原型链操作小结  制作网站的软件下载免费,今日头条开宝箱老是需要下载怎么回事?  如何基于云服务器快速搭建网站及云盘系统?  建站主机默认首页配置指南:核心功能与访问路径优化  宁波免费建站如何选择可靠模板与平台?  网站制作的软件有哪些,制作微信公众号除了秀米还有哪些比较好用的平台?  如何用已有域名快速搭建网站?  韩国服务器如何优化跨境访问实现高效连接?  建站之星在线客服如何快速接入解答?  TestNG的testng.xml配置文件怎么写  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  制作网站的网址是什么,请问后缀为.com和.com.cn还有.cn的这三种网站是分别是什么类型的网站?  在线ppt制作网站有哪些,请推荐几个好的课件下载的网站?  企业网站制作公司网页,推荐几家专业的天津网站制作公司?  常州自助建站:操作简便模板丰富,企业个人快速搭建网站  c# F# 的 MailboxProcessor 和 C# 的 Actor 模型  宝塔建站助手安装配置与建站模板使用全流程解析  建站之星2.7模板快速切换与批量管理功能操作指南  宝塔新建站点为何无法访问?如何排查?  如何在阿里云虚拟主机上快速搭建个人网站?  Android自定义listview布局实现上拉加载下拉刷新功能  企业在线网站设计制作流程,想建设一个属于自己的企业网站,该如何去做?  手机钓鱼网站怎么制作视频,怎样拦截钓鱼网站。怎么办?  定制建站模板如何实现SEO优化与智能系统配置?18字教程  网站设计制作企业有哪些,抖音官网主页怎么设置?  贸易公司网站制作流程,出口贸易网站设计怎么做?  建站10G流量真的够用吗?如何应对访问高峰?  建站主机服务器选购指南:轻量应用与VPS配置解析  如何通过网站建站时间优化SEO与用户体验?  营销式网站制作方案,销售哪个网站招聘效果最好?  简历在线制作网站免费,免费下载个人简历的网站是哪些?  c++怎么使用类型萃取type_traits_c++ 模板元编程类型判断【方法】  制作充值网站的软件,做人力招聘为什么要自己交端口钱?  如何快速选择适合个人网站的云服务器配置?  定制建站策划方案_专业建站与网站建设方案一站式指南  制作门户网站的参考文献在哪,小说网站怎么建立?  建站之星2.7模板:企业网站建设与h5定制设计专题  再谈Python中的字符串与字符编码(推荐)  郑州企业网站制作公司,郑州招聘网站有哪些?  如何在宝塔面板中修改默认建站目录?  如何在服务器上配置二级域名建站?  胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?  如何在IIS中新建站点并解决端口绑定冲突?  北京网站制作费用多少,建立一个公司网站的费用.有哪些部分,分别要多少钱?  如何通过云梦建站系统实现SEO快速优化?  道歉网站制作流程,世纪佳缘致歉小吴事件,相亲网站身份信息伪造该如何稽查?  香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南  香港服务器网站生成指南:免费资源整合与高速稳定配置方案  标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。