眾所周知,React的壹個優點就是它的API非常簡單。通過render方法返回壹個組件的基本結構,就像壹個簡單的函數壹樣,就可以得到壹個可重用的react組件。但是有時候會有壹些限制,特別是在他的API中,無法控制組件應該渲染到的DOM節點,導致壹些彈性層組件很難控制。當父元素設置為overflow:hidden時會出現問題。
例如,像這樣:
我們實際期望的效果是這樣的:
幸運的是,雖然不明顯,但有壹個相當優雅的方法可以繞過這個問題。我們學的第壹個react函數是render方法,它的函數簽名如下:
ReactComponent呈現(
遙測元件,
DOMElement容器,
[函數回調]
)
通常我們使用這種方法將整個應用程序呈現給壹個DOM節點。好消息是這種方法並不局限於此。我們可以使用ReactDom.render方法將另壹個組件呈現到壹個組件中的指定DOM元素中。作為組件的render方法,必須是純的(比如不能改變狀態,不能和DOM交互)。所以我們需要在componentDidUpdate或者componentDidMount中調用ReactDom.render方法。
此外,我們需要確保當父元素被卸載時,被修改的組件也被卸載。
經過整理,我們得到以下組件:
從“react”導入React,{ Component };
從“react-dom”導入ReactDom
導出默認類RenderInBody擴展組件{
構造者(p){
super();
}
ComponentIdMount(){//創建壹個新的div標記,並將其插入主體。
this . popup = document . createelement(" div ");
document . body . appendchild(this . popup);
這個。_ render layer();
}
componentDidUpdate() {
這個。_ render layer();
}
ComponentWillUnmount(){//卸載組件時,確保彈性層也被卸載。
react DOM . unmountcomponentatnode(this . popup);
document . body . remove child(this . popup);
}
_renderLayer(){//將彈性層渲染到正文下的div標簽。
react DOM . render(this . props . children,this . popup);
}
render(){
返回null
}
}
總而言之:
當componentDidMount時,手動將壹個div標記插入主體,然後使用ReactDom.render將組件呈現到該div標記。
當我們想把組件直接渲染到主體上時,只需要在組件周圍包裹壹層RenderInBody即可。
“導出默認類”對話框擴展組件{
render(){
返回{
& ltRenderInBody & gt我是壹個對話框渲染體& lt/render inbody & gt;
}
}
}
譯者補充道:
通過轉換上述組件,我們可以將組件呈現和卸載到指定的dom節點,並添加位置控制,如下所示:
//這個組件用來渲染主體內部的彈性層。
從“react”導入React,{Component}
從“react-dom”導入ReactDom
導出默認類RenderInBody擴展組件{
構造者(p){
超(p);
}
componentidmount(){
/**
popupInfo={
RootDom:***,//接收炸彈層組件的Dom節點,如document.body
左:***,//相對位置
Top:***//位置信息
}
*/
let { popupInfo } = this.props
this . popup = document . createelement(' div ');
this . rootdom = popup info . rootdom;
this . rootdom . appendchild(this . popup);
//我們只能用這種方法設置div的屬性
this . popup . style . position = ' absolute ';
this . popup . style . left = popup info . left+' px ';
this . popup . style . top = popup info . top+' px ';
這個。_renderLayer()
}
componentDidUpdate() {
這個。_ render layer();
}
componentWillUnmount(){
this . rootdom . remove child(this . popup);
}
_renderLayer(){
react DOM . render(this . props . children,this . popup);
}
render(){
返回null
}
}
註:位置獲取和根節點判斷功能
導出默認值(dom,class filters)= & gt;{
let left = dom.offsetLeft,
top = DOM . offsettop+DOM . scroll top,
current = dom.offsetParent,
root DOM = accessBodyElement(DOM);//默認為body。
而(當前!=null ) {
left+= current . offset left;
top+= current . offsettop;
current = current.offsetParent
如果(當前& amp& ampcurrent . matches(class filters)){
rootDom = current
打破;
}
}
return { left: left,top: top,root DOM:rootDom };
}
/***
1.dom:響應彈性層的dom節點,或者到達dom的位置後,可以對位置進行微調,使彈性層的位置更合適。
*
2.classFilters:需要接收彈性層組件的DOM節點的過濾器類名。
/
原始地址
摘要