在Next.js新App Router中实现MUI模态框拦截浏览器返回键关闭
实现模态框打开时劫持浏览器返回键的方案
核心实现思路
- 监听模态框的
open状态,打开时添加浏览器popstate事件拦截返回操作 - 打开模态框时往历史栈中新增一条当前页面记录,避免直接回退到上一页
- 关闭模态框或组件卸载时清理事件监听与历史记录,保证状态一致性
修改后的完整代码
"use client" import { Modal } from '@mui/material' import { useState, useEffect } from 'react' export default function Component() { const [open, setOpen] = useState(false) useEffect(() => { const handlePopState = () => { if (open) { setOpen(false) } } if (open) { // 新增历史记录,防止返回键直接跳转到上一页 window.history.pushState({ modalOpen: true }, '') window.addEventListener('popstate', handlePopState) } else { window.removeEventListener('popstate', handlePopState) } // 组件卸载时清理监听与历史记录 return () => { window.removeEventListener('popstate', handlePopState) if (open) { window.history.back() } } }, [open]) // 自定义关闭逻辑,同步清理历史记录 const handleClose = () => { setOpen(false) window.history.back() } return ( <> <Modal open={open} onClose={handleClose} style={{ display: "flex", alignItems: "center", justifyContent: "center" }} > <div style={{ background: "white", padding: "100px" }}> hi </div> </Modal> <button onClick={() => setOpen(true)}> open modal </button> </> ) }
关键细节说明
popstate事件拦截:触发浏览器返回时,若模态框处于打开状态则直接关闭模态框- 历史栈处理:打开模态框时新增的历史记录,让返回操作仅触发
popstate而非页面跳转 - 内存泄漏防护:在
useEffect的清理函数中移除事件监听,组件卸载时同步恢复历史栈状态 - 关闭逻辑同步:自定义
handleClose函数确保关闭模态框时,历史栈也能回到之前的状态
内容的提问来源于stack exchange,提问作者Ts1
相关产品推荐
相关产品推荐

