我正在使用T3堆栈和tRPC,并面临着跨不同路由的查询无效的挑战。我的应用程序有两个路由:/profile
和/student-profile
。
On /profile
:我显示一个包含特定任务(“TODO”项)数据的列表。On /student-profile
:用户可以使用两个按钮接受或拒绝学生的任务。
在/student-profile
上执行了一个突变(接受或拒绝学生)后,我需要使/profile
上的任务列表数据无效,以相应地更新它。然而,即使突变成功,也不会触发无效,正如我的日志所证实的那样。
我意识到,当导航到/student-profile
时,“list”查询变得不活动,从而防止无效。
这是我的限制:我想避免为这个查询设置refetchOnMount: true
或cacheTime: 0
。原因是为了防止每次访问/profile
页面时都进行额外的网络请求。这对于减少不必要的网络流量和改善用户体验至关重要。
我的问题是:在这个设置中,我如何有效地使来自另一个路由(/student-profile)的非活动查询(
/profile上的列表)无效,同时遵守不频繁重新获取数据的约束?T3堆栈中的tRPC中是否有特定的方法来处理这种情况? 在这个问题上的任何指导或见解都将非常有帮助。 在此先谢谢您!
/profile`路由
const {data: tasks, isFetching} = api.tasks.getInterestedTasksByAuthorId.useQuery({
authorId: user.id
}, {
refetchOnMount: false,
refetchOnWindowFocus: false,
});
字符串/student-profile
路由
const acceptStudent = api.tasks.acceptStudent.useMutation({
async onSuccess() {
try {
await utils.tasks.getInterestedTasksByAuthorId.invalidate()
} catch (e) {
console.error(e)
}
},
});
const handleAcceptStudent = async () => {
await acceptStudent.mutateAsync({
studentId,
taskId
})
}
型
1条答案
按热度按时间332nm8kg1#
如何有效地使非活动查询无效
有几种方法可以直接在你的mutation回调中做到这一点:
filters
,在这里你可以指定一个默认为'active'
的refetchType
。将它设置为'all'
来重新获取所有匹配的查询,即使是那些不活跃的查询:字符串
请注意,在trpc中,过滤器是第二个参数,因此如果没有输入,则需要将
undefined
作为第一个参数传递。.refetch
来代替.invalidate
,这与使用refetchType: 'all'
进行无效操作的效果几乎相同:型
这两种方法的问题在于,它们只针对它们匹配的 * 所有内容 *。这可能对您的情况有效,但让我们考虑一下,您的todo项目可以被过滤或搜索。由于react-query具有文档缓存,因此您将有多个缓存条目(每个输入一个),将匹配。所以,如果你有3个潜在的待办事项列表在你的缓存,都是不活动的,他们都将重新获取现场,即使用户可能永远不会回到它们。
这就是为什么无效通常是首选,它只会标记为过时的项目是不活跃的,只会重新获取他们的时候,用户请求他们下一次。
原因是为了防止每次访问/profile页面时都发出额外的网络请求。
事情是这样的:您不需要为此调整
refetchOnMount
之类的标志。为资源设置高staleTime
是首选方法。如果您将staleTime
设置为20分钟,这意味着数据将在20分钟内被认为是新鲜的,因此对useQuery
的每次调用都只会在此时间段内从该高速缓存读取数据,因为像refetchOnMount
和refetchOnWindowFocus
等标志只会在事件发生时重新获取被认为过时的数据。因为即使你将
staleTime
设置为Infinity
(意思是:它将永远是新鲜的),调用invalidateQueries()
本质上会覆盖它。因此,我的首选方法是将所有标志保留在默认设置上,根据我的喜好定制
staleTime
,并使用默认的invalidate()
方法,因为它需要编写和维护的代码量最少,用户体验最好,而且永远不会不必要地过度提取。