Files
simple-react-app-kit/packages/overlays/docs/zh-Hans/advanced/lifecycle.mdx
T
2026-09-28 23:13:44 +08:00

65 lines
2.3 KiB
Plaintext

---
title: 生命周期与路由拦截
description: 理解结果、队列、Host 生命周期以及路由库适配。
order: 20
toc:
- id: result-contracts
title: 结果约定
- id: queue
title: 队列与 Host
- id: dismissal
title: 关闭行为
- id: navigation
title: 路由拦截
---
## 结果约定 {#result-contracts}
`openConfirm` 使用 `false` 表示取消,`openPrompt` 使用 `null`,自定义 Modal、Sheet 和 Drawer 使用 `undefined` 表示没有结果。`close(value)` 会根据 `openModal<Result>()` 的泛型检查结果。
```tsx
import { openModal } from "@workspace/overlays/modal"
const productId = await openModal<string>({
title: "选择产品",
content: ({ close }) => (
<ProductPicker onSelect={(product) => close(product.id)} />
),
})
```
## 队列与 Host {#queue}
同一个 Scope 中,每种 feature 都有一个按需创建的 channel 和 Base UI handle。同类调用进入 FIFO 队列,前一个关闭动画结束后才显示下一个。不同 feature 可以同时显示,例如 Modal 内可以继续打开 Confirm。
Host 卸载时会用取消值结算它仍在等待的请求。React Strict Mode 的模拟卸载不会错误取消请求。
## 关闭行为 {#dismissal}
自定义内容可以调用 `dismiss()`。关闭按钮、Escape 和遮罩点击也进入取消路径。设置 `dismissible: false` 会阻止外部关闭,但内容仍可以显式调用 `close(result)` 或 `dismiss()`。
## 路由拦截 {#navigation}
`@workspace/overlays/navigation` 只依赖 Scope,不依赖具体 overlay feature 或路由库:
```tsx
import { OverlayNavigationGuard } from "@workspace/overlays/navigation"
const adapter: OverlayNavigationAdapter = {
subscribe(listener) {
return router.block((transition) => {
listener({
cancel: transition.reset,
proceed: transition.retry,
})
})
},
}
<OverlayNavigationGuard adapter={adapter} />
```
默认 Guard 检查当前和命名局部 Scope,找到最后打开的浮层。如果允许 dismiss,则关闭浮层并取消跳转;`dismissible: false` 会保留浮层并继续阻止跳转;没有浮层时才调用 `proceed()`。
适配器的 `proceed()` 必须继续已经被阻塞的同一次跳转,不能重新发起一个会再次触发 blocker 的导航。需要不同策略时,可以传入自定义 `interceptor`。