完成后你将能够
能只在表单有未保存修改时注册阻塞器,并正确连接继续、留下与关闭标签页行为。
阻塞条件应来自真实脏状态
shouldBlockFn 返回 true 表示阻止导航。enableBeforeUnload 负责刷新、关闭标签页等浏览器级卸载;应当只在 isDirty 为 true 时启用,避免用户离开干净页面也收到系统提示。
自定义确认需要 resolver
withResolver: true 时,status 变为 blocked 后再显示界面。proceed 允许本次导航,reset 保持当前页面。保存成功后先清除脏状态,避免后续导航再次被旧状态拦截。
import { useBlocker } from '@tanstack/react-router'
function LeaveGuard({ isDirty }: { isDirty: boolean }) {
const blocker = useBlocker({
shouldBlockFn: () => isDirty,
enableBeforeUnload: isDirty,
withResolver: true,
})
if (blocker.status !== 'blocked') return null
return <div role="alertdialog" aria-modal="true" aria-labelledby="leave-title">
<h2 id="leave-title">Discard unsaved changes?</h2>
<button type="button" onClick={blocker.proceed}>Leave</button>
<button type="button" onClick={blocker.reset}>Stay</button>
</div>
}把本课变成可验证的能力
只有表单为脏时才阻止客户端导航和页面卸载,保存成功后立即解除。
实现继续离开、留在页面和保存后离开三条流程,并为每条流程编写交互测试。
测试 Link、后退、刷新和保存四种行为;确认框只应在未保存状态出现。
- 所有导航都弹确认框,即使表单没有变化。
- 只拦截 Router 导航而漏掉浏览器关闭或刷新。