浏览文档目录
Agent docs/router/navigation-blocker
recipe

保护脏表单的离页导航

用 useBlocker 的 resolver 状态实现可访问的离页确认,并按脏状态注册 beforeunload。

View raw Markdown
CONTRACT

执行契约

适用场景
离开当前路由会丢失明确可检测的未保存用户输入。
不要使用
不要阻止只会丢失可重新获取数据或无价值临时 UI 状态的导航。
前置检查
定义可靠的 isDirty、保存成功后的重置动作,以及浏览器卸载策略。
验证结果
覆盖 Link、前进后退、刷新、关闭标签页和保存后离开;未修改状态不得出现提示。
失败模式
保存后仍提示通常表示 Mutation 成功路径没有同步重置 dirty 状态。
安全边界
阻止导航只能保护体验,不能作为持久化、草稿恢复或并发写入控制。
01

阻塞语义

shouldBlockFn 返回 true 表示阻止。withResolver: true 时,其返回值只决定是否进入 blocked 状态;之后必须由 proceed 或 reset 解决本次导航。

02

最小 resolver

enableBeforeUnload 使用相同脏状态,覆盖刷新与关闭标签页。自定义对话框应有明确可访问名称、键盘操作和焦点管理;下面只展示 Router 状态契约。

src/features/editor/useLeaveBlocker.tstsx
import { useBlocker } from '@tanstack/react-router'

export function useLeaveBlocker(isDirty: boolean) {
  return useBlocker({
    shouldBlockFn: () => isDirty,
    enableBeforeUnload: isDirty,
    withResolver: true,
  })
}
03

验证清单

验证干净表单不阻塞;脏表单的 Link、后退、刷新和关闭标签页得到正确行为;proceed 继续,reset 留下;保存成功清除脏状态。浏览器对 beforeunload 使用系统对话框,文案不可完全自定义。

PRIMARY SOURCEShttps://tanstack.com/router/latest/docs/guide/navigation-blocking