React.createPortal()


https://blog.csdn.net/sd19871122/article/details/97612107

https://blog.csdn.net/mmzzll2019/article/details/89348085?utm_medium=distribute.pc_relevant.none-task-blog-title-3&spm=1001.2101.3001.4242

createProtal 改造 Modal 組件

在 html 中除了 div#root 之外,給 Modal 預留了一個新的 div#modal-root,:

  1. const appRoot = document.getElementById('root');
  2. const modalRoot = document.getElementById('modal-root');

改造 Modal 容器

新的 Modal 容器組件內容如下:  

class ModalContainer extends Component {

constructor(props) {super(props);

this.el = document.createElement('div');}

componentDidMount()

{modalRoot.appendChild(this.el);}

componentWillUnmount()

{modalRoot.removeChild(this.el);}

render() {return ReactDOM.createPortal(this.props.children,this.el);}}

 將 ModalContent 掛載到 ModalContainer 

class App2 extends Component {

state = {

name: 'clickme'

}

componentDidMount(){

// console.log(findDOMNode(ref.current))

}

clickHandle = () => {

this.setState({

name: 'clickme' + Date.now()

});

}

render() {

return (

<div className="App">

<ModalContainer>

<ModalContent />

</ModalContainer>

</div>);

}}

創建一個Foo組件(表現為200*200的div),放到body的中央位置。

import React from "react";
import ReactDom from "react-dom";

export default class extends React.Component {
div = document.createElement("div");

componentWillUnmount() {
document.body.removeChild(this.div);
}

componentDidMount() {
document.body.appendChild(this.div);
}

render() {
return ReactDom.createPortal(<Foo />, this.div);
}
}

const styles = {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 200,
height: 200,
zIndex: 100,
background: "rgba(222,222,222,0.4)",
boxShadow: "5px 5px 5px 5px gray"
};
const Foo = () => {
return <div style={styles}>Portals的使用</div>;
};

 

Portals的事件傳遞

import React from "react";
import ReactDom from "react-dom";

class App extends React.Component {
div = document.createElement("div");

componentWillUnmount() {
document.body.removeChild(this.div);
}

componentDidMount() {
document.body.appendChild(this.div);
}

render() {
return ReactDom.createPortal(<Foo />, this.div);
}
}

const styles = {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
width: 200,
height: 200,
zIndex: 100,
background: "rgba(222,222,222,0.4)",
boxShadow: "5px 5px 5px 5px gray"
};
const Foo = () => {
return (
<div onClick={() => console.info("觸發點擊事件")} style={styles}>
Portals的使用
</div>
);
};

export default () => (
<div
style={{ border: "1px solid red" }}
onClick={() => console.info("點擊事件冒泡到其React的虛擬DOM父節點")}
>
<p>React虛擬DOM父節點</p>
<App />
</div>
);

 事件的傳遞有效,在Foo組件觸發的click事件,依然會傳遞到App組件

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM