查看: 37|回复: 0

React.createPortal()

[复制链接]

4

主题

0

回帖

0

积分

热心网友

金币
0
阅读权限
220
精华
0
威望
0
贡献
0
在线时间
0 小时
注册时间
2011-3-10
发表于 2020-9-23 15:13:00 | 显示全部楼层 |阅读模式

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组件

 



来源:https://www.cnblogs.com/zwjun/p/13718562.html
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

相关侵权、举报、投诉及建议等,请发 E-mail:qiongdian@foxmail.com

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部