在 React 项目中使用路由的形式打开弹框
分类: React 2568 4
前言
由于之前一直都是在使用 Vue
做项目,遇见的弹框基本都是通过显示隐藏实现的弹框,最近开始在做 React
项目,发现一种新的模式,在 React
里面可以通过路由的形式打开弹框,也比较好奇具体怎么实现的,在一些特定的场景下路由的形式会比一般通过显示隐藏来的更方便,比如前端是使用的微前端模式,各个模块的前端都是完全独立的,如果想在一个模块打开另一个模块的某个弹框,在使用显示与隐藏的形式需要找到组件的记录的状态然后在去更改,首先是组件的状态不好拿到,也不好维护,如果通过路由的形式打开弹框,即可轻松解决这个问题,只需要在这个模块跳转路由即可,路由打开还有个方便之处可以很方便的解决刷新之后弹框依旧需要展示的问题。
实现原理
在 React 里面,一切皆组件。
举例:一共有 home、about 两个页面,共三个组件,页面 home 对应组件 Home
,页面 about 对应 About
组件,弹框则对应 Dialog
组件,弹框是在 home 页面打开,home 页面的路径为 /
,弹框的路径为 /dialog
,about 页面路径为 /about
,react-router 在不加精准匹配 exact
的模式下是可以匹配到多个组件的,核心就是使用这个模式完成,一个页面也是组件,如果按照上边的举例,当我们在浏览器输入 /dialog
一共会匹配到两个组件,即 Home、Dialog,效果如下:
具体实现
由于 class
组件比较重,我这里使用函数组件实现,具体实现需要用到 react-router
、ReactDOM.createPortal
。
ReactDOM.createPortal
用法摘自官网:https://zh-hans.reactjs.org/docs/portals.htmlPortal
提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。意思就是可以将一个 React 组件渲染到页面已有的元素内。 具体语法:ReactDOM.createPortal(child, container)
,第一个参数是一个React.Node
,第二个是需要将节点渲染到哪里的具体容器。
- 第一步准备一个弹框组件,使用
position: fixed
将弹框定位在页面的最上层,通过ReactDOM.createPortal
将组件渲染到body
,外层通过Route
组件将弹框包裹起来,组件接收两个props
,分别为path
、onClose
,并在调用地址设置一个路径,这里示例使用/dialog
作为弹框组件的路径。 >path
用于弹框组件的路由,即react-router
路径参数onClose
用于接收弹框关闭的事件
具体代码如下:
// 弹框组件
function Dialog(props) {
const history = useHistory()
// 渲染弹框内容
function DialogContent() {
return <div className=dialog-content>{props.children}</div>;
}
// 弹框关闭事件
function onClose() {
history.go(-1)
props?.onClose()
}
// 将弹框渲染到 body
return ReactDOM.createPortal(
<Route path={props.path}>
<div className=dialog onClick={onClose}>
<DialogContent />
</div>
</Route>,
document.body
)
}
- 第二步准备具体渲染页面用的组件,
Home
、About
两个组件,代码如下
function Home() {
const history = useHistory();
// 点击打开弹框
function handleShowDialog() {
history.push('/dialog');
}
return (
<>
<div>Home</div>
<span
style={{ color: '#00f', cursor: 'pointer' }}
onClick={handleShowDialog}>
Dialog
</span>
</>
);
}
function About() {
return <div>About</div>;
}
- 第三步准备渲染完整页面的代码
function App() {
function onClose() {
console.log('弹框关闭了~')
}
return (
<>
<Link to=/>Home</Link>
<Link to=/about>About</Link>
<Switch>
<Route path=/about>
<About />
</Route>
<Route path=/>
<Home />
</Route>
</Switch>
<Dialog path=/dialog onClose={onClose}>我是弹框内容,点我可以关闭啦~</Dialog>
</>
);
}
共 4 条评论关于 “在 React 项目中使用路由的形式打开弹框”