1. 程式人生 > >React在body下追加全域性元件並實現渲染更新

React在body下追加全域性元件並實現渲染更新

元件化對前端來講已是家常便飯,各種功能效果實現之後,冷不防產品又想讓在另一個模組呼叫。簡單,Ctrl + c + v一通操作,幾十遍幾十上百行程式碼不嫌煩的話完全OK的哈~。像我這麼懶的人肯定是要利用元件一勞永逸哇。我們平時寫的元件一般是在當前頁面的某個元素節點下面使用,要是碰上一些蒙層或是需要置於頂層覆蓋的元件,避免元素的隱藏屬性則需要將元件放置於頁面外層。儲存執行,哎喲臥槽怎麼還有個節點蓋在上面,找出css加上z-index這才安心。在使用antui的時候會發現alert,popup的彈出層都是插入在body節點下面的,這就可以很舒服地決解避免被其他元素隱藏和層級問題,維護性較高。

這個牛皮啊怎麼搞得,媽我學。這就需要用到ReactDOM.render,簡單實現一下:

1、工具類的方法


class Utils {
constructor () {}
alert (view) {
let div = document.createElement('div')
view = view || <button>確定</button>
ReactDOM.render(view, div)
document.body.appendChild(div)
}
}
// 方法和css樣式寫入全域性檔案,需要用到的地方 utils.alert() 呼叫即可

2、react元件。由上述方法生成的react節點是不繼承state和props屬性的,若想在之後做節點狀態修改,渲染重新整理,就需要將方法放進react元件裡,通過生命週期控制。


import ReactDOM from 'react-dom'
import React, { Component } from 'react';

class PopupMask extends Component {
constructor(props) {
super(props)
}
retContainer () {
if (!this.popupNode) {
const popupNode = document.createElement('div')
popupNode.setAttribute('id', 'popup_mask')
this.popupNode = popupNode
document.body.appendChild(popupNode)
}
return this.popupNode
}
retContent () {
return (
<div className="popup_content">
{this.props.children}
</div>
)
}
componentDidUpdate () {
//當父級模組更新時,直接粗暴地執行渲染,該api跨節點渲染,理同ReactDOM.render
ReactDOM.unstable_renderSubtreeIntoContainer(
this,
this.retContent(),
this.retContainer(),
)
}
render() {
return null //此處需返回null 避免報錯
}
}

export default PopupMask

// 這樣會就可以愉快地使用了
// import PopupMask from 'components/PopupMask/PopupMask.jsx';
// 引入的元件放哪裡都可以,當前模組執行render方法時會重新渲染
{/* <PopupMask className="">
<div>真香警告</div>
</PopupMask> */}

此操作困擾我一時,總覺得就這樣暴力執行render真的好?翻閱無數資料無果,後託大佬扣出ant的popup元件,發現ant裡面也是這麼寫的,頓時就放心了。