|
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,:
-
const appRoot = document.getElementById('root');
-
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(){
}
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组件
来源:https://www.cnblogs.com/zwjun/p/13718562.html |