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%)",
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%)",
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组件

原文地址:https://www.cnblogs.com/zwjun/p/13718562.html