首頁  >  文章  >  web前端  >  React將元件渲染到指定DOM節點的方法詳解

React將元件渲染到指定DOM節點的方法詳解

巴扎黑
巴扎黑原創
2017-09-09 10:17:552592瀏覽

這篇文章主要給大家介紹了關於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(){//新建一个p标签并塞进body
  this.popup = document.createElement("p");
  document.body.appendChild(this.popup);
  this._renderLayer();
 }
 componentDidUpdate() {
  this._renderLayer();
 }
 componentWillUnmount(){//在组件卸载的时候,保证弹层也被卸载掉
  ReactDom.unmountComponentAtNode(this.popup);
  document.body.removeChild(this.popup);
 }
 _renderLayer(){//将弹层渲染到body下的p标签
  ReactDom.render(this.props.children, this.popup);
 }
 render(){
  return null;
 }
}

總結下就是:

在componentDidMount的時候手動向body內塞一個p標籤,然後使用ReactDom.render 將元件渲染到這個p標籤

當我們想把元件直接渲染到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 &#39;react&#39;
import ReactDom from &#39;react-dom&#39;;
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(&#39;p&#39;);
  this.rootDom = popupInfo.rootDom;  
  this.rootDom.appendChild(this.popup);
  //we can setAttribute of the p only in this way
  this.popup.style.position=&#39;absolute&#39;;
  this.popup.style.left=popupInfo.left+&#39;px&#39;;
  this.popup.style.top=popupInfo.top+&#39;px&#39;;
  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节点的筛选类名
/

以上是React將元件渲染到指定DOM節點的方法詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn