由于 TanStack Router 不存储或缓存数据,它在数据变更中的作用微乎其微,主要是在于响应来自外部变更事件的潜在 URL 副作用。即便如此,我们还是整理了一份与变更相关的功能列表,您可能会觉得有用,以及实现这些功能的库。
查找并使用支持以下功能的变更实用程序
一些建议的库
或者,甚至...
与数据获取类似,变更状态并非一劳永逸的解决方案,因此您需要选择适合您和您团队需求的解决方案。我们建议尝试几种不同的解决方案,看看哪种最适合您。
⚠️ 还在看吗?提交状态在持久性方面是一个有趣的话题。您会永远保留每个变更吗?您如何知道何时摆脱它?如果用户离开屏幕然后又返回怎么办?让我们深入探讨一下!
TanStack Router 内置了短期缓存。因此,即使在路由匹配卸载后我们不存储任何数据,如果对 Router 中存储的数据进行任何变更,当前路由匹配的数据也很有可能变得陈旧。
当进行与加载器数据相关的变更时,我们可以使用 router.invalidate
强制路由器重新加载所有当前路由匹配
const router = useRouter()
const addTodo = async (todo: Todo) => {
try {
await api.addTodo()
router.invalidate()
} catch {
//
}
}
const router = useRouter()
const addTodo = async (todo: Todo) => {
try {
await api.addTodo()
router.invalidate()
} catch {
//
}
}
使所有当前路由匹配失效在后台发生,因此现有数据将继续提供服务,直到新数据准备就绪,就像您导航到新路由一样。
如果您想等待失效直到所有加载器完成,请将 {sync: true}
传递到 router.invalidate
中
const router = useRouter()
const addTodo = async (todo: Todo) => {
try {
await api.addTodo()
await router.invalidate({ sync: true })
} catch {
//
}
}
const router = useRouter()
const addTodo = async (todo: Todo) => {
try {
await api.addTodo()
await router.invalidate({ sync: true })
} catch {
//
}
}
无论使用哪种变更库,变更通常都会创建与其提交相关的状态。虽然大多数变更是即设即忘的,但有些变更状态寿命更长,要么是为了支持乐观 UI,要么是为了向用户提供有关其提交状态的反馈。大多数状态管理器都会正确地保留此提交状态并公开它,以便可以显示 UI 元素,如加载指示器、成功消息、错误消息等。
让我们考虑以下交互
/posts/123/edit
屏幕以编辑帖子123
帖子,并在成功后,在编辑器下方看到帖子已更新的成功消息/posts
屏幕/posts/123/edit
屏幕如果不通知您的变更管理库有关路由更改,则您的提交状态可能仍然存在,并且当用户返回上一个屏幕时,仍然会看到 “帖子已成功更新” 消息。这并不理想。显然,我们的意图不是永远保留此变更状态,对吧?!
希望且假设地,最简单的方法是让您的变更库支持一种键控机制,该机制允许在键更改时重置您的变更状态
const routeApi = getRouteApi('/posts/$postId/edit')
function EditPost() {
const { roomId } = routeApi.useParams()
const sendMessageMutation = useCoolMutation({
fn: sendMessage,
// Clear the mutation state when the roomId changes
// including any submission state
key: ['sendMessage', roomId],
})
// Fire off a bunch of messages
const test = () => {
sendMessageMutation.mutate({ roomId, message: 'Hello!' })
sendMessageMutation.mutate({ roomId, message: 'How are you?' })
sendMessageMutation.mutate({ roomId, message: 'Goodbye!' })
}
return (
<>
{sendMessageMutation.submissions.map((submission) => {
return (
<div>
<div>{submission.status}</div>
<div>{submission.message}</div>
</div>
)
})}
</>
)
}
const routeApi = getRouteApi('/posts/$postId/edit')
function EditPost() {
const { roomId } = routeApi.useParams()
const sendMessageMutation = useCoolMutation({
fn: sendMessage,
// Clear the mutation state when the roomId changes
// including any submission state
key: ['sendMessage', roomId],
})
// Fire off a bunch of messages
const test = () => {
sendMessageMutation.mutate({ roomId, message: 'Hello!' })
sendMessageMutation.mutate({ roomId, message: 'How are you?' })
sendMessageMutation.mutate({ roomId, message: 'Goodbye!' })
}
return (
<>
{sendMessageMutation.submissions.map((submission) => {
return (
<div>
<div>{submission.status}</div>
<div>{submission.message}</div>
</div>
)
})}
</>
)
}
router.subscribe
方法对于没有键控机制的库,我们可能需要在用户离开屏幕时手动重置变更状态。为了解决这个问题,我们可以使用 TanStack Router 的 invalidate
和 subscribe
方法在用户不再需要它们时清除变更状态。
router.subscribe
方法是一个函数,它将回调订阅到各种路由器事件。我们在这里特别使用的事件是 onResolved
事件。重要的是要理解,此事件在位置路径*已更改(不仅仅是重新加载)并最终解析*时触发。
这是一个重置旧变更状态的好地方。这是一个示例
const router = createRouter()
const coolMutationCache = createCoolMutationCache()
const unsubscribeFn = router.subscribe('onResolved', () => {
// Reset mutation states when the route changes
coolMutationCache.clear()
})
const router = createRouter()
const coolMutationCache = createCoolMutationCache()
const unsubscribeFn = router.subscribe('onResolved', () => {
// Reset mutation states when the route changes
coolMutationCache.clear()
})
您的每周 JavaScript 新闻。每周一免费发送给超过 10 万名开发者。