Skip to content

Commit d9ae665

Browse files
authored
Merge pull request #1085 from reduxjs/docs/rtkq-overview
2 parents 06e8f32 + f3a0c62 commit d9ae665

File tree

4 files changed

+145
-7
lines changed

4 files changed

+145
-7
lines changed

query-old/docs/introduction/comparison.md renamed to docs/rtk-query/comparison.md

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,55 @@
11
---
22
id: comparison
3-
title: Comparison
4-
sidebar_label: Comparison
3+
title: Comparison with Other Tools
4+
sidebar_label: Comparison with Other Tools
55
hide_title: true
6-
hide_table_of_contents: true
76
---
87

9-
# Comparison
8+
# Comparison with Other Tools
109

11-
RTK Query takes inspiration from many other data fetching libraries in the ecosystem. Much like [the Redux core library was inspired by tools like Flux and Elm](https://redux.js.org/understanding/history-and-design/prior-art), RTK Query builds on API design patterns and feature concepts popularized by libraries like React Query, SWR, Apollo, and Urql. RTK Query has been written from scratch, but tries to use the best concepts from those libraries and other data fetching tools, with an eye towards leveraging the unique strengths and capabilities of Redux.
10+
**RTK Query takes inspiration from many other data fetching libraries in the ecosystem**. Much like [the Redux core library was inspired by tools like Flux and Elm](https://redux.js.org/understanding/history-and-design/prior-art), RTK Query builds on API design patterns and feature concepts popularized by libraries like React Query, SWR, Apollo, and Urql. RTK Query has been written from scratch, but tries to use the best concepts from those libraries and other data fetching tools, with an eye towards leveraging the unique strengths and capabilities of Redux.
11+
12+
We think that all of those tools are great! If you're using one of them, you're happy with it, and it solves the problems you are facing in your app, keep using that tool. The information on this page is meant to help show **where there are differences in features, implementation approaches, and API design**. The goal is to help you **make informed decisions and understand tradeoffs**, rather than argue that tool X is better than tool Y.
13+
14+
## When Should You Use RTK Query?
15+
16+
In general, the main reasons to use RTK Query are:
17+
18+
- You already have a Redux app and you want to simplify your existing data fetching logic
19+
- You want to be able to use the Redux DevTools to see the history of changes to your state over time
20+
- You want to be able to integrate the RTK Query behavior with the rest of the Redux ecosystem
21+
- Your app logic needs to work outside of React
22+
23+
### Unique Capabilities
24+
25+
RTK Query has some unique API design aspects and capabilities that are worth considering.
26+
27+
- With React Query and SWR, you usually define your hooks yourself, and you can do that all over the place and on the fly. With RTK Query, you do so in one central place by defining an "API slice" with multiple endpoints ahead of time. This allows for a more tightly integrated model of mutations automatically invalidating/refetching queries on trigger.
28+
- With the endpoint [matcher functionality](./api/created-api/endpoints#matchers): Every request is automatically is visible to your Redux reducers and can easily update the global application state if necessary ([see example](https://github.com/reduxjs/redux-toolkit/issues/958#issuecomment-809570419)).
29+
- You can easily invalidate entities or patch existing query data (via `util.updateQueryData`) from middleware.
30+
- RTK Query enables [streaming cache updates](./usage/streaming-updates.mdx), such as updating the initial fetched data as messages are received over a websocket, and has built in support for [optimistic updates](./usage/optimistic-updates.mdx) as well.
31+
- Like Redux itself, the main RTK Query functionality is UI-agnostic and can be used with any UI layer
32+
- RTK Query ships a very tiny and flexible fetch wrapper: [`fetchBaseQuery`](./api/fetchBaseQuery.mdx). It's also very easy to [swap our client with your own](./usage/customizing-queries.mdx), such as using `axios`, `redaxios`, or something custom.
33+
- RTK Query has [a (currently experimental) code-gen tool](https://github.com/rtk-incubator/rtk-query-codegen) that will take an OpenAPI spec and give you a typed API client, as well as provide methods for enhancing the generated client after the fact.
34+
35+
## Tradeoffs
36+
37+
### No Normalized or Deduplicated Cache
38+
39+
RTK Query deliberately **does _not_ implement a cache that would deduplicate identical items across multiple requests**. There are several reasons for this:
40+
41+
- A fully normalized shared-across-queries cache is a _hard_ problem to solve
42+
- We don't have the time, resources, or interest in trying to solve that right now
43+
- In many cases, simply refetching data when it's invalidated works well and is easier to understand
44+
- At a minimum, RTKQ can help solve the general use case of "fetch some data", which is a big pain point for a lot of people
45+
46+
## Comparing Feature Sets
1247

1348
It's worth comparing the feature sets of all these tools to get a sense of their similarities and differences.
1449

1550
:::info
1651

17-
This comparison table strives to be as accurate and as unbiased as possible. If you use any of these libraries and feel the information could be improved, feel free to suggest changes (with notes or evidence of claims) by [opening an issue](https://github.com/rtk-incubator/rtk-query/issues/new).
52+
This comparison table strives to be as accurate and as unbiased as possible. If you use any of these libraries and feel the information could be improved, feel free to suggest changes (with notes or evidence of claims) by [opening an issue](https://github.com/reduxjs/redux-toolkit/issues/new).
1853

1954
:::
2055

@@ -37,3 +72,9 @@ This comparison table strives to be as accurate and as unbiased as possible. If
3772
| **Optimistic updates** | can update cache by hand | can update cache by hand | `optimisticResponse` | ? |
3873
| **Manual cache manipulation** | yes | yes | yes | yes |
3974
| **Platforms** | hooks for React, everywhere Redux works | hooks for React | various | various |
75+
76+
## Further Information
77+
78+
- The [React Query "Comparison" page](https://react-query.tanstack.com/comparison) has an additional detailed feature set comparison table and discussion of capabilities
79+
- Urql maintainer Phil Pluckthun wrote [an excellent explanation of what a "normalized cache" is and how Urql's cache works](https://kitten.sh/graphql-normalized-caching)
80+
- The [RTK Query "Cached Data" page](./usage/cached-data.mdx#tradeoffs) has further details on why RTK Query does not implement a normalized cache

docs/rtk-query/overview.md

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
id: overview
3+
title: RTK Query Overview
4+
sidebar_label: RTK Query Overview
5+
hide_title: true
6+
---
7+
8+
# RTK Query Overview
9+
10+
**RTK Query** is a powerful data fetching and caching tool. It is designed to simplify common cases for loading data in a web application, **eliminating the need to hand-write data fetching & caching logic yourself**.
11+
12+
RTK Query is **an optional addon included in the Redux Toolkit package**, and its functionality is built on top of the other APIs in Redux Toolkit.
13+
14+
### Motivation
15+
16+
Web applications normally need to fetch data from a server in order to display it. They also usually need to make updates to that data, send those updates to the server, and keep the cached data on the client in sync with the data on the server. This is made more complicated by the need to implement other behaviors used in today's applications:
17+
18+
- Tracking loading state in order to show UI spinners
19+
- Avoiding duplicate requests for the same data
20+
- Optimistic updates to make the UI feel faster
21+
- Managing cache lifetimes as the user interacts with the UI
22+
23+
The Redux core has always been very minimal - it's up to developers to write all the actual logic. That means that Redux has never included anything built in to help solve these use cases. The Redux docs have taught [some common patterns for dispatching actions around the request lifecycle to track loading state and request results](https://redux.js.org/tutorials/fundamentals/part-7-standard-patterns#async-request-status), and [Redux Toolkit's `createAsyncThunk` API](../api/createAsyncThunk.mdx) was designed to abstract that typical pattern. However, users still have to write significant amounts of reducer logic to manage the loading state and the cached data.
24+
25+
Over the last couple years, the React community has come to realize that **"data fetching and caching" is really a different set of concerns than "state management"**. While you can use a state management library like Redux to cache data, the use cases are different enough that it's worth using tools that are purpose-built for the data fetching use case.
26+
27+
RTK Query takes inspiration from other tools that have pioneered solutions for data fetching, like Apollo Client, React Query, Urql, and SWR, but adds a unique approach to its API design:
28+
29+
- The data fetching and caching logic is built on top of Redux Toolkit's `createSlice` and `createAsyncThunk` APIs
30+
- Because Redux Toolkit is UI-agnostic, RTK Query's functionality can be used with any UI layer
31+
- API endpoints are defined ahead of time, including how to generate query parameters from arguments and transform responses for caching
32+
- RTK Query can also generate React hooks that encapsulate the entire data fetching process, provide `data` and `isFetching` fields to components, and manage the lifetime of cached data as components mount and unmount
33+
- Finally, RTK Query is completely written in TypeScript, and is designed to provide an excellent TS usage experience
34+
35+
### What's included
36+
37+
RTK Query is included within the installation of the core Redux Toolkit package. It is available via either of the two entry points below:
38+
39+
```ts no-transpile
40+
import { createApi } from '@reduxjs/toolkit/query'
41+
42+
/* React-specific entry point that automatically generates
43+
hooks corresponding to the defined endpoints */
44+
import { createApi } from '@reduxjs/toolkit/query/react'
45+
```
46+
47+
RTK Query includes these APIs:
48+
49+
- [`createApi()`](./api/createApi.mdx): The core of RTK Query's functionality. It allows you to define a set of endpoints describe how to retrieve data from a series of endpoints, including configuration of how to fetch and transform that data.
50+
- [`fetchBaseQuery()`](./api/fetchBaseQuery.mdx): A small wrapper around [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) that aims to simply requests. Intended as the recommended `baseQuery` to be used in `createApi` for the majority of users.
51+
- [`<ApiProvider />`](./api/ApiProvider.mdx): Can be used as a `Provider` if you **do not already have a Redux store**.
52+
- [`setupListeners()`](./api/setupListeners.mdx): A utility used to enable `refetchOnMount` and `refetchOnReconnect` behaviors.
53+
54+
## Further Information
55+
56+
See the [RTK Query Quick Start tutorial](../tutorials/rtk-query.mdx/) for examples of how to add RTK Query to a project that uses Redux Toolkit, set up an "API slice" with endpoint definitions, and how to use the auto-generated React hooks in your components.
57+
58+
The [RTK Query usage guide section](./usage/queries.mdx) has information on topics like [querying data](./usage/queries.mdx), [using mutations to send updates to the server](./usage/mutations.mdx), [streaming cache updates](./usage/streaming-updates.mdx), and much more.
59+
60+
The [Examples page](./usage/examples.mdx) has runnable CodeSandboxes that demonstrate topics like [making queries with GraphQL](./usage/examples.mdx#react-with-graphql), [authentication](./usage/examples.mdx#authentication), and even [using RTK Query with other UI libraries like Svelte](./usage/examples.mdx#svelte).

docs/rtk-query/usage/cached-data.mdx

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -984,3 +984,35 @@ const api = createApi({
984984
```
985985

986986
An example of various abstractions for tag providing/invalidating designed for common rest data formats can be seen in the following gist, including typescript support, and factoring both ['LIST' style advanced tag invalidation](#advanced-invalidation-with-abstract-tag-ids) and ['error' style tag invalidation](#providing-errors-to-the-cache): **[RTK Query cache utils](https://gist.github.com/Shrugsy/6b6af02aef1f783df9d636526c1e05fa)**.
987+
988+
## Tradeoffs
989+
990+
### No Normalized or Deduplicated Cache
991+
992+
RTK Query deliberately **does _not_ implement a cache that would deduplicate identical items across multiple requests**. There are several reasons for this:
993+
994+
- A fully normalized shared-across-queries cache is a _hard_ problem to solve
995+
- We don't have the time, resources, or interest in trying to solve that right now
996+
- In many cases, simply refetching data when it's invalidated works well and is easier to understand
997+
- At a minimum, RTKQ can help solve the general use case of "fetch some data", which is a big pain point for a lot of people
998+
999+
As an example, say that we have an API slice with `getTodos` and `getTodo` endpoints, and our components make the following queries:
1000+
1001+
- `getTodos()`
1002+
- `getTodos({filter: 'odd'})`
1003+
- `getTodo({id: 1})`
1004+
1005+
Each of these query results would include a Todo object that looks like `{id: 1}`.
1006+
1007+
In a fully normalized deduplicating cache, only a single copy of this Todo object would be stored. However, RTK Query saves each query result independently in the cache. So, this would result in three separate copies of this Todo being cached in the Redux store. However, if all the endpoints are consistently providing the same tags (such as `{type: 'Todo', id: 1}`), then invalidating that tag will force all the matching endpoints to refetch their data for consistency.
1008+
1009+
The Redux docs have always recommended [keeping data in a normalized lookup table](https://redux.js.org/recipes/structuring-reducers/normalizing-state-shape) to enable easily finding items by ID and updating them in the store, and [RTK's `createEntityAdapter`](../../api/createEntityAdapter.mdx) was designed to help manage normalized state. Those concepts are still valuable and don't go away. However, if you're using RTK Query to manage caching data, there's less need to manipulate the data that way yourself.
1010+
1011+
There are a couple additional points that can help here:
1012+
1013+
- The generated query hooks have [a `selectFromResult` option](../api/created-api/hooks.mdx) that allow components to read individual pieces of data from a query result. As an example, a `<TodoList>` component might call `useTodosQuery()`, and each individual `<TodoListItem>` could use the same query hook but select from the result to get the right todo object.
1014+
- You can use the [`transformResponse` endpoint option](../api/createApi.mdx) to modify the fetched data so that it's stored in a different shape, such as using `createEntityAdapter` to normalize the data _for this one response_ before it's inserted into the cache.
1015+
1016+
## Further information
1017+
1018+
- [Reddit: discussion of why RTKQ doesn't have a normalized cache, and tradeoffs](https://www.reddit.com/r/reactjs/comments/my9vrq/redux_toolkit_v16_alpha1_rtk_query_apis/gvxi5t7/)

website/sidebars.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
{
3131
"type": "category",
3232
"label": "API Reference",
33+
"collapsed": true,
3334
"items": [
3435
{
3536
"type": "category",
@@ -69,10 +70,14 @@
6970
{
7071
"type": "category",
7172
"label": "RTK Query",
73+
"collapsed": false,
7274
"items": [
75+
"rtk-query/overview",
76+
"rtk-query/comparison",
7377
{
7478
"type": "category",
7579
"label": "Using RTK Query",
80+
"collapsed": true,
7681
"items": [
7782
"rtk-query/usage/queries",
7883
"rtk-query/usage/mutations",
@@ -95,7 +100,7 @@
95100
{
96101
"type": "category",
97102
"label": "API Reference",
98-
"collapsed": false,
103+
"collapsed": true,
99104
"items": [
100105
"rtk-query/api/createApi",
101106
"rtk-query/api/fetchBaseQuery",

0 commit comments

Comments
 (0)