最近学习的时候,看到一个比较有意思的api,一开始看比较懵逼,后来看了程摩Morgan大佬的文章(文章在这里),感觉豁然开朗,故记录一下。
- 什么是传送门?
传送门的意思就是,组件从一个门进去,然后从另一个门出去。举个栗子,假如在我们生活的空间里有一个传送门,然后再天堂也有一个传送门,当我们从我们这边的传送门进去,我们就可以到天堂了。
- 为什么要传送门?
这个时候可能有人就会说了:“哎呀,你说的我都懂,你就直接告诉我它有啥用吧!" 不知道大家在开发的过程中有没有需要开发对话框的场景,大家都知道,对于用户的感觉来说,对话框应该是一个独立的组件,同时应该脱离文档流居中,并且只有在用户做对用的操作的时候才显示出来。假如我们有很多个页面,然后每个页面都有对话框,这时候大家肯定会想把对话框单独抽出来做成一个组件,但是既然需要每个页面都要用到,所以这个组件应该独立性很高,但是当我们把它放到具体的页面的时候,它可能是当前这个页面的子组件,然后当你对他定位的时候,可能会发现对话框不听话了,这是因为绝对定位是按照父组件的第一个非static进行定位的,你没办法保证它的左右父组件都是static。当然你也可以像上面文章中提到的用其它的方法解决这一问题,但是会比较复杂,我这边就不赘述了,感兴趣可以看看大佬的文章。
- 如何使用?
我这边直接在root下面手动添加了一个节点,后面我们将会把对话框挂到这个节点上。
下面是App.js的代码
import React, { useState } from "react";
import "./styles.css";
import Button from "./father";
export default function App() {
const [showDialog, setShowDialog] = useState(false);
function changeShowDialog() {
setShowDialog(!showDialog);
}
return (
<div className="App">
<h1>This is App</h1>
<Button showDialog={showDialog} changeShowDialog={changeShowDialog} />
</div>
);}
father.ja代码
import React from "react";
import Dialog from "./portal";
function Button(props) {
const { showDialog, changeShowDialog } = props;
return (
<div className="father" onClick={changeShowDialog}> //用来接收子组件的冒泡
<button onClick={changeShowDialog}>open</button>
<div onClick={() => console.log("传送出来了")}> //用来接收子组件的冒泡
{showDialog ? <Dialog /> : null}
</div>
</div> );
}
export default Button;
protal.js代码
import { createPortal } from "react-dom";
import React from "react";
function Dailog() {
return createPortal(
<div className="dialog"> // 对话框
<h1>我是弹窗</h1>
<button>关闭</button>
</div>,
document.getElementById("dialog") // 将挂载的root同级节点
);
}
export default Dailog;
styles.css
.App {
font-family: sans-serif;
text-align: center;
}
.father {
width: 500px;
height: 300px;
background-color: red;
position: relative;
}
.dialog {
width: 200px;
height: 100px;
background-color: aqua;
position: absolute;
top: 50%;
left: 50%;
transform: translate3d(-50%, -50%, 0);
}
演示效果
对话框的效果大概就这样了,因为它挂载到了界面的另一个地方,所以它的定位不会受到root节点下定位的影响,同时值得一提的是,它不仅可以将一个组件传送到另一个组件,这个组件被传送的组件的事件却还可以冒泡回去它得父节点,就相当于我穿越到了天上,但是我在天上拉的屎还可以通过传送门传回人间,很神奇。
怎么样,是不是很神奇有用的的一个api,如果觉得我这边说的不是很清楚,那你可以去看看大佬的文章,如果觉得我有说的不对的地方希望可以不吝赐教。