这个 `queryArg` 在 Redux Toolkit Query 的 hooks 中是用来做什么的?

huangapple go评论76阅读模式
英文:

what does this queryArg do in redux toolkit query for its hooks?

问题

useGetNotesQuery 方法中的 "notesList" 是一个查询标识符,用于标识此查询的名称或键。这个标识符在内部用于生成回调 URL,以便与后端进行通信。它有助于识别和管理不同的查询,以及将查询结果存储在缓存中,以便以后可以重复使用,从而提高性能。

getNotes(/notesList/) 是一个查询缓存键,用于识别特定查询的结果。它允许多个 useGetNotesQuery 实例共享相同的缓存键,以便它们可以检查缓存中是否已有相同查询的结果,而不必重新发起网络请求。

提供和无效化标签(tags)在 notesApiSlice 中的作用是管理缓存数据的细粒度控制。通过提供和无效化标签,您可以手动控制何时刷新或无效化缓存数据,而不必依赖于默认的缓存策略。这样,您可以更灵活地处理数据的缓存和刷新,以满足您的具体需求。

因此,"notesList" 和标签(tags)都是用于管理查询缓存的不同机制,它们可以根据您的需求进行组合使用,以实现更精细的控制和性能优化。

英文:
} = useGetNotesQuery("notesList", {
  // options available via setupListeners(store.dispatch) in store.js
  // want it to update more often so only 15 seconds
  pollingInterval: 15000,
  refetchOnFocus: true,
  refetchOnMountOrArgChange: true,
});

I'm trying to understand what passing in "notesList" does as the query arg via https://redux-toolkit.js.org/rtk-query/usage/queries. The docs say it generates the callback url, but why do I need this? My getNotes endpoint already goes to "/notes" in my builder function/endpoints.

I notice in my redux dev tools, after subscription is fulfilled, it's stored as querycachekey (getNotes(/notesList/). What does this do? If this is a cache key so that other instances of useGetNotesQuery can share the same key and check the cache first, then what is the point of providing and invaliding tags inside notesApiSlice (where getNotes provides tags) and mutations obviously invalidate tags? Why do I need cache keys like "notesList" if I already have the provided and invalidated tags inside my endpoints?

答案1

得分: 1

@phry的回答已经很好地解释了queryArg在查询中的作用,所以我不会再详细讨论这一部分。看起来你的问题更多关于RTK在生成缓存键和缓存结果方面对查询参数的处理。

我注意到在redux开发工具中,订阅完成后,它被存储为querycachekey (getNotes(/notesList/))。这是做什么用的?如果这是一个缓存键,以便其他useGetNotesQuery的实例可以共享相同的键并首先检查缓存,那么在notesApiSlice(其中getNotes提供标签)内提供和使标签失效的目的是什么?而且突变显然使标签失效?为什么我需要像"notesList"这样的缓存键,如果我已经在我的端点内提供了和使标签失效了呢?

缓存键和查询标签有两个不同的目的。我首先快速介绍一下标签,以便清楚它们与缓存键是不同的。

标签

"提供标签"和"使标签失效"仅在引用相同标签的查询和突变之间使用。如果你查询了一些特定的数据并提供了特定的标签,然后稍后进行突变以使该特定标签失效,那么任何提供该标签的活动查询钩子都会"自动"立即重新查询它们的端点以获取最新的突变数据。

将标签视为一种"信号",也就是说如果突变将标签标记为失效或"脏",那么对该标签的查询应该再次运行并验证/重新验证,或者"干净"该标签。

有关更多信息或更深入的了解,请参阅自动重新获取

缓存键

缓存键允许你节省不必要的网络请求,因为后端数据很可能没有更新。假设你有一个用于获取体育队统计数据的端点,钩子是useGetTeamStats

UI发出查询请求以获取当前选择的球队,比如Tigers,id为"2139hsdfkj30iy"

useGetTeamStats("2139hsdfkj30iy")

API请求被发送,响应返回,现在为查询参数"2139hsdfkj30iy"创建了一个缓存条目。几秒钟后,用户选择了另一个球队,比如Bears,id为"0934tjner9lknw"

useGetTeamStats("0934tjner9lknw")

再次发送API请求,响应返回,为查询参数"0934tjner9lknw"创建了另一个缓存条目。

现在你在redux中有两个缓存结果。这里发生了一些魔法。如果用户然后返回并选择Tigers,钩子再次发出查询请求。

useGetTeamStats("2139hsdfkj30iy")

不同的是,这次有一个缓存命中,键为"2139hsdfkj30iy"!不需要向后端发送网络请求,钩子只是返回缓存的响应数据。只要数据被缓存,就不会进行网络请求。活动查询订阅者会保持缓存的有效性,还有一个keepUnusedDataFor端点配置属性,它在订阅结束后保持缓存活动X秒。如果另一个组件挂载并在keepUnusedDataFor到期之前进行相同的查询,缓存数据就会返回。默认的keepUnusedDataFor是60秒。

你可以阅读更多关于缓存行为的信息。

简而言之

标签用于帮助自动重新获取数据,缓存用于节省不必要的网络流量。

英文:

@phry's answer explains well enough what purpose the queryArg serves in terms of making queries, so I won't double down on that part. It seems your question is more about what RTK does with the query argument in relation to generating cache keys and caching results.

> I notice in my redux dev tools, after subscription is fulfilled, it's
> stored as querycachekey (getNotes(/notesList/). What does this do? If
> this is a cache key so that other instances of useGetNotesQuery can
> share the same key and check the cache first, then what is the point
> of providing and invaliding tags inside notesApiSlice (where
> getNotes provides tags) and mutations obviously invalidate tags? Why
> do I need cache keys like "notesList" if I already have the provided
> and invalidated tags inside my endpoints?

Cache keys and query tags serve two separate purposes. I'll first quickly cover what the tags do so it's clear they are different than cache keys.

Tags

The "provides tags" and "invalidates tags" are only used between queries and mutations that reference the same tags. If you've queried some specific data and provided a specific tag, and then later make a mutation that invalidates that specific tag, then any active query hooks that provide that tag "auto-magically" immediately re-query their endpoint to fetch the latest mutated data.

Think of tags more of a "signal", that is to say if a mutation marks a tag as invalid, or "dirty", that a query for that tag should run again and validate/revalidate, or "clean", the tag.

For more information, or a deeper dive, see Automated Re-fetching.

Cache Keys

What the cache keys allow you to do is save making unnecessary network requests for data that likely hasn't updated in the backend. Let's pretend you have an endpoint that fetches stats for sports teams, the hook is useGetTeamStats.

The UI makes a query for the current selected team, the Tigers, id is "2139hsdfkj30iy".

useGetTeamStats("2139hsdfkj30iy")

The API request is made, a response is returned, and now a cache entry is made for the query arg "2139hsdfkj30iy". Seconds later the user selects a different team, the Bears, id is "0934tjner9lknw".

useGetTeamStats("0934tjner9lknw")

Again, the API request is made, a response is returned, and another cache entry is made for the query arg "0934tjner9lknw".

You've now two cached results in redux. Here's where some magic happens. If the user then goes back and selects the Tigers, the hook again makes the query request.

useGetTeamStats("2139hsdfkj30iy")

What is different this time though is that there's a cache hit for the key "2139hsdfkj30iy"! Instead of making the network request to the backend, the hook simply returns the cached response data. So long as the data is cached, no network requests will be made. Active query subscribers keep the caches alive, and there's a keepUnusedDataFor endpoint configuration property that keeps the cache around for X seconds after subscriptions end. If another component mounts and makes the same query prior to the keepUnusedDataFor expiration, the cache data is returned. The default keepUnusedDataFor is 60 seconds.

You can read more about the Cache Behavior.

TL;DR

Tags are used to help automate refetching of data, the cache is used to save unnecessary network traffic.

答案2

得分: 0

你的端点可以使用这个参数来做一些有用的事情。

想象一下像这样的情况

useNotesPageQuery(3)

与一个具有以下查询函数的端点

query: arg => '/notes?page='+arg

并不是每个端点都只有一个静态的 URL。如果你有一个像这样的端点,你可以只传递 undefined 进去 - 但大多数情况下它们会接受某种参数。

英文:

Your endpoint could use this argument for something useful.

Imagine something like

useNotesPageQuery(3)

with and endpoint that has a query function like

query: arg => '/notes?page='+arg

Not every endpoint will only have a static url. If you have an endpoint like that, you can just pass undefined in - but most of them will take some kind of argument.

huangapple
  • 本文由 发表于 2023年5月18日 05:12:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/76276239.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定