您好,登錄后才能下訂單哦!
這篇文章主要介紹React將組件渲染到指定DOM節(jié)點的示例,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
前言
眾所周知React優(yōu)點之一就是他的API特別簡單。通過render 方法返回一個組件的基本結構,如同一個簡單的函數(shù),就可以得到一個可以復用的react組件。但是有時候還是會有些限制的,尤其是他的API中,不能控制組件所應該渲染到的DOM節(jié)點,這就讓一些彈層組件很難控制。當父元素設置為overflow:hidden
的時候,問題就會出現(xiàn)了。
例如就像下面的這樣:
我們實際期待的效果是這樣的:
幸運的是,雖然不是很明顯,但有一個相當優(yōu)雅的方式來繞過這個問題。我們學到的第一個react函數(shù)是render 方法,他的函數(shù)簽名是這樣的:
ReactComponent render( ReactElement element, DOMElement container, [function callback] )
通常情況下我們使用該方法將整個應用渲染到一個DOM節(jié)點中。好消息是該方法并不僅僅局限于此。我們可以在一個組件中,使用ReactDom.render
方法將另一個組件渲染到一個指定的DOM 元素中。作為一個組件的render 方法,其必須是純凈的(例如:不能改變state或者與DOM交互).所以我們需要在componentDidUpdate 或者 componentDidMount 中調(diào)用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內(nèi)塞一個div標簽,然后使用ReactDom.render 將組件渲染到這個div標簽
當我們想把組件直接渲染到body上的時候,只需要在該組件的外面包一層RenderInBody 就可以了.
export default class Dialog extends Component{ render(){ return { <RenderInBody>i am a dialog render to body</RenderInBody> } } }
譯者增加:
將以上組件改造一下,我們就可以向指定的dom節(jié)點中渲染和卸載組件,并加上位置控制,如下:
//此組件用于在body內(nèi)渲染彈層 import React,{Component} from 'react' import ReactDom from 'react-dom'; export default class RenderInBody extends Component{ constructor(p){ super(p); } componentDidMount(){ /** popupInfo={ rootDom:***,//接收彈層組件的DOM節(jié)點,如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; } }
注:位置獲取和根結點判斷函數(shù)
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節(jié)點,或者到該dom的位置后,可以做位置的微調(diào),讓彈層位置更佳合適 * 2. classFilters:需要接收彈層組件的DOM節(jié)點的篩選類名 /
以上是“React將組件渲染到指定DOM節(jié)點的示例”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關知識,歡迎關注億速云行業(yè)資訊頻道!
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。