React.createPortal()

<https://blog.csdn.net/sd19871122/article/details/97612107&gt;

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

声明:该文章系转载,转载该文章的目的在于更广泛的传递信息,并不代表本网站赞同其观点,文章内容仅供参考。

本站是一个个人学习和交流平台,网站上部分文章为网站管理员和网友从相关媒体转载而来,并不用于任何商业目的,内容为作者个人观点, 并不代表本网站赞同其观点和对其真实性负责。

我们已经尽可能的对作者和来源进行了通告,但是可能由于能力有限或疏忽,导致作者和来源有误,亦可能您并不期望您的作品在我们的网站上发布。我们为这些问题向您致歉,如果您在我站上发现此类问题,请及时联系我们,我们将根据您的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。