You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 07:11:08