路由掩码是一种掩盖路由实际 URL 的方法,该 URL 会持久化到浏览器的历史记录和 URL 栏中。这在您想要显示与实际导航到的 URL 不同的 URL,然后在共享时(以及可选地在页面重新加载时)回退到显示的 URL 的场景中非常有用。以下是一些示例
每个场景都可以通过路由掩码来实现,甚至可以扩展以支持更高级的模式,例如 并行路由。
重要提示
您不需要理解路由掩码的工作原理即可使用它。本节适用于那些对底层工作原理感到好奇的人。跳到如何使用路由掩码?以学习如何使用它!
路由掩码利用 location.state API 将所需的运行时 location 存储在将写入 URL 的 location 内部。它将此运行时 location 存储在 __tempLocation state 属性下
const location = {
pathname: '/photos/5',
search: '',
hash: '',
state: {
key: 'wesdfs',
__tempKey: 'sadfasd',
__tempLocation: {
pathname: '/photo/5/modal',
search: '',
hash: '',
state: {},
},
},
}
const location = {
pathname: '/photos/5',
search: '',
hash: '',
state: {
key: 'wesdfs',
__tempKey: 'sadfasd',
__tempLocation: {
pathname: '/photo/5/modal',
search: '',
hash: '',
state: {},
},
},
}
当路由器从历史记录中解析带有 location.state.__tempLocation 属性的 location 时,它将使用该 location 而不是从 URL 解析的 location。这允许您导航到类似 /photos/5 的路由,并让路由器实际导航到 /photo/5/modal。发生这种情况时,历史记录 location 将保存回 location.maskedLocation 属性中,以防我们需要知道实际 URL 是什么。Devtools 中就使用了这个,我们可以在 Devtools 中检测路由是否被掩盖,并显示实际 URL 而不是掩盖的 URL!
请记住,您无需担心任何这些。这一切都在幕后自动处理!
路由掩码是一个简单的 API,可以通过 2 种方式使用
当使用任一路由掩码 API 时,mask 选项接受与 <Link> 和 navigate() API 接受的相同的导航对象。这意味着您可以使用您已经熟悉的相同 to、replace、state 和 search 选项。唯一的区别是 mask 选项将用于掩盖正在导航到的路由的 URL。
🧠 mask 选项也是类型安全的!这意味着如果您正在使用 TypeScript,如果您尝试将无效的导航对象传递给 mask 选项,您将收到类型错误。好耶!
<Link> 和 navigate() API 都接受一个 mask 选项,该选项可用于掩盖正在导航到的路由的 URL。这是一个在 <Link> 组件中使用它的示例
<Link
to="/photos/$photoId/modal"
params={{ photoId: 5 }}
mask={{
to: '/photos/$photoId',
params: {
photoId: 5,
},
}}
>
Open Photo
</Link>
<Link
to="/photos/$photoId/modal"
params={{ photoId: 5 }}
mask={{
to: '/photos/$photoId',
params: {
photoId: 5,
},
}}
>
Open Photo
</Link>
这是在 navigate() API 中使用它的示例
const navigate = useNavigate()
function onOpenPhoto() {
navigate({
to: '/photos/$photoId/modal',
params: { photoId: 5 },
mask: {
to: '/photos/$photoId',
params: {
photoId: 5,
},
},
})
}
const navigate = useNavigate()
function onOpenPhoto() {
navigate({
to: '/photos/$photoId/modal',
params: { photoId: 5 },
mask: {
to: '/photos/$photoId',
params: {
photoId: 5,
},
},
})
}
除了命令式 API 之外,您还可以使用 Router 的 routeMasks 选项来声明式地掩盖路由。您无需将 mask 选项传递给每个 <Link> 或 navigate() 调用,而是可以在 Router 上创建一个路由掩码,以掩盖与特定模式匹配的路由。这是一个与上面相同的路由掩码示例,但使用了 routeMasks 选项
// 以下示例使用以下代码
import { createRouteMask } from '@tanstack/react-router'
const photoModalToPhotoMask = createRouteMask({
routeTree,
from: '/photos/$photoId/modal',
to: '/photos/$photoId',
params: (prev) => ({
photoId: prev.photoId,
}),
})
const router = createRouter({
routeTree,
routeMasks: [photoModalToPhotoMask],
})
import { createRouteMask } from '@tanstack/react-router'
const photoModalToPhotoMask = createRouteMask({
routeTree,
from: '/photos/$photoId/modal',
to: '/photos/$photoId',
params: (prev) => ({
photoId: prev.photoId,
}),
})
const router = createRouter({
routeTree,
routeMasks: [photoModalToPhotoMask],
})
创建路由掩码时,您需要传递 1 个参数,其中至少包含
🧠 createRouteMask 选项也是类型安全的!这意味着如果您正在使用 TypeScript,如果您尝试将无效的路由掩码传递给 routeMasks 选项,您将收到类型错误。
URL 在共享时会自动取消掩码,因为一旦 URL 从浏览器的本地历史记录堆栈中分离,URL 掩码数据将不再可用。本质上,一旦您从历史记录中复制并粘贴 URL,其掩码数据就会丢失……毕竟,这就是掩码 URL 的目的!
默认情况下,在本地重新加载页面时,URL 不会取消掩码。掩码数据存储在历史记录 location 的 location.state 属性中,因此只要历史记录 location 仍在历史记录堆栈的内存中,掩码数据就可用,URL 将继续被掩盖。
如上所述,默认情况下,在页面重新加载时,URL 不会取消掩码.
如果您希望在页面重新加载时在本地取消掩码 URL,您有 3 个选项,如果传递,每个选项都会覆盖前一个选项的优先级
您的每周 JavaScript 新闻。每周一免费发送给超过 100,000 名开发者。