Skip to content

Commit f94e9d3

Browse files
committed
📝 Clarify query loading states
* Add clarity on distinction & use-cases for `isLoading` vs `isFetching` * Re-order query page sections * Fix broken links
1 parent 037e772 commit f94e9d3

File tree

1 file changed

+43
-6
lines changed

1 file changed

+43
-6
lines changed

docs/rtk-query/usage/queries.mdx

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ const api = createApi({
7777

7878
### Performing Queries with React Hooks
7979

80-
If you're using React Hooks, RTK Query does a few additional things for you. The primary benefit is that you get a render-optimized hook that allows you to have 'background fetching' as well as [derived booleans](#query-hook-return-types) for convenience.
80+
If you're using React Hooks, RTK Query does a few additional things for you. The primary benefit is that you get a render-optimized hook that allows you to have 'background fetching' as well as [derived booleans](#frequently-used-query-hook-return-values) for convenience.
8181

8282
Hooks are automatically generated based on the name of the `endpoint` in the service definition. An endpoint field with `getPost: builder.query()` will generate a hook named `useGetPostQuery`.
8383

@@ -152,6 +152,47 @@ The way that this component is setup would have some nice traits:
152152
2. When the request is re-triggered by the polling interval, it will add '...refetching' to the post name
153153
3. If a user closed this `PostDetail`, but then re-opened it within [the allowed time](../api/createApi#keepunuseddatafor), they would immediately be served a cached result and polling would resume with the previous behavior.
154154

155+
### Query Loading State
156+
157+
The auto-generated React hooks created by the React-specific version of `createApi` provide [derived booleans](#frequently-used-query-hook-return-values) that reflect the current state of a given query. Derived booleans are preferred for the generated React hooks as opposed to a `status` flag, as the derived booleans are able to provide a greater amount of detail which would not be possible with a single `status` flag, as multiple statuses may be true at a given time (such as `isFetching` and `isSuccess`).
158+
159+
For query endpoints, RTK Query maintains a semantic distinction between `isLoading` and `isFetching` in order to provide more flexibility with the derived information provided.
160+
161+
- `isLoading` refers to a query being in flight for the _first time_ for the given endpoint + query param combination. No data will be available at this time.
162+
- `isFetching` refers to a query being in flight for the given endpoint + query param combination, but not necessarily for the first time. Data may be available from an earlier request at this time.
163+
164+
This distinction allows for greater control when handling UI behavior. For example, `isLoading` can be used to display a skeleton while loading for the first time, while `isFetching` can be used to grey out old data when fetching subsequent requests when data is invalidated and re-fetched.
165+
166+
```tsx title="Managing UI behavior with Query Loading States"
167+
import { Skeleton } from './Skeleton'
168+
import { useGetPostsQuery } from './api'
169+
170+
function App() {
171+
const { data = [], isLoading, isFetching, isError } = useGetPostsQuery()
172+
173+
if (isError) return <div>An error has occurred!</div>
174+
175+
if (isLoading) return <Skeleton />
176+
177+
return (
178+
<div className={isFetching ? 'posts--disabled' : ''}>
179+
{data.map((post) => (
180+
<Post
181+
key={post.id}
182+
id={post.id}
183+
name={post.name}
184+
disabled={isFetching}
185+
/>
186+
))}
187+
</div>
188+
)
189+
}
190+
```
191+
192+
### Query Cache Keys
193+
194+
When you perform a query, RTK Query automatically serializes the request parameters and creates an internal `queryCacheKey` for the request. Any future request that produces the same `queryCacheKey` will be de-duped against the original, and will share updates if a `refetch` is trigged on the query from any subscribed component.
195+
155196
### Selecting data from a query result
156197

157198
Sometimes you may have a parent component that is subscribed to a query, and then in a child component you want to pick an item from that query. In most cases you don't want to perform an additional request for a `getItemById`-type query when you know that you already have the result.
@@ -183,10 +224,6 @@ function PostById({ id }: { id: number }) {
183224
}
184225
```
185226

186-
### Query Cache Keys
187-
188-
When you perform a query, RTK Query automatically serializes the request parameters and creates an internal `queryCacheKey` for the request. Any future request that produces the same `queryCacheKey` will be de-duped against the original, and will share updates if a `refetch` is trigged on the query from any subscribed component.
189-
190227
### Avoiding unnecessary requests
191228

192229
By default, if you add a component that makes the same query as an existing one, no request will be performed.
@@ -218,7 +255,7 @@ Click the 'Add bulbasaur' button. You'll observe the same behavior described abo
218255
:::
219256
220257
<iframe
221-
src="https://codesandbox.io/embed/github/reduxjs/redux-toolkit/tree/feature/v1.6-integration/examples/query/react/deduping-caching?fontsize=12&hidenavigation=1&theme=dark"
258+
src="https://codesandbox.io/embed/github/reduxjs/redux-toolkit/tree/feature/v1.6-integration/examples/query/react/deduping-queries?fontsize=12&hidenavigation=1&theme=dark"
222259
style={{
223260
width: '100%',
224261
height: '800px',

0 commit comments

Comments
 (0)