Technology handbook
Redux Toolkit
Modern Redux setup, slices, async thunks, entity adapters, listeners and RTK Query.
- Topics
- 37
- Sections
- 5
Hooks
Generated endpoint hooks
createApi turns every endpoint into its own typed query or mutation hook.
- Use the React-specific RTK Query entry point for generated hooks.
- Query hooks subscribe to endpoint-and-argument cache entries.
- Mutation hooks return a trigger and request status.
useQuery options
skip, pollingInterval and refetchOnMountOrArgChange are decided per call site, not per endpoint.
- skip controls whether the hook subscribes and fetches.
- pollingInterval schedules refreshes while subscribed.
- Refetch options control reuse of an existing cached result.
useLazyQuery
Trigger a query from an event rather than on render, and keep the last result.
- Call the lazy trigger when the initiating event occurs.
- Await its result when subsequent work depends on the response.
- Handle loading and failure states for the triggered argument.
useMutation
Take the trigger function and the request state as one tuple, and reset it deliberately.
- Call the trigger with the mutation's argument payload.
- Use unwrap to handle success and failure with ordinary promises.
- Reset displayed mutation state when its UI flow ends.
usePrefetch
Warm the cache on hover or route entry before the user asks for the data.
- Trigger prefetch for a likely upcoming query argument.
- Use age or force options to control cache warming.
- Prefetching alone does not create a lasting component subscription.
useQueryState and useQuerySubscription
Split reading cached data from subscribing to it when two components share one query.
- useQueryState reads cached query status and data.
- useQuerySubscription owns fetching and subscription behavior.
- Keep both hooks aligned on the same endpoint argument.
selectFromResult
Narrow what a component subscribes to inside a query result it shares with others.
- Return only fields the consuming component needs.
- Preserve references in the selected result when data is unchanged.
- Hoist stable empty defaults instead of creating new arrays.
Typed useAppDispatch and useAppSelector
Pre-typed wrappers so every call site keeps the store's own types.
- Infer dispatch and state types from configureStore.
- Reuse typed hooks throughout feature components.
- Keep type-only imports separate to avoid runtime cycles.
Tag-driven refetching
Endpoint tags decide which hooks refetch after a mutation, instead of manual invalidation calls.
- Declare provided tags on queries and invalidated tags on mutations.
- Active subscriptions refetch when matching tags are invalidated.
- Use entity IDs to avoid refreshing unrelated query results.
RTK Query
createApi and baseQuery
Define a server-data API slice with shared request behavior and endpoint contracts.
- Choose a base query that returns data or error consistently.
- Register the API reducer and middleware in the store.
- Centralize headers and request transformation at the API boundary.
Query endpoints
Cache reads by endpoint and serialized arguments and subscribe through generated hooks.
- Define read operations as queries with explicit argument types.
- The endpoint and serialized argument identify the cached request.
- Share cache entries across equivalent active subscriptions.
Mutation endpoints
Represent server writes and define how successful changes affect cached queries.
- Define write operations with their request and result types.
- Invalidate relevant query tags after server state changes.
- Handle mutation errors independently from cached read data.
Cache tags and invalidation
Invalidate the smallest relevant group of cached results after a mutation.
- Provide tags that describe records or list membership.
- Invalidate affected IDs after successful changes.
- Use broader list tags when insertions affect collection results.
Polling and refetch policies
Balance freshness with bandwidth using focus, reconnect and polling behavior.
- Enable focus and reconnect behavior with setupListeners.
- Choose polling intervals that match actual freshness needs.
- Stop unnecessary polling when the consuming view is absent.
Optimistic updates
Patch cached data immediately and roll back or invalidate when a mutation fails.
- Apply a cache patch before the server confirms the mutation.
- Undo the patch on failure when reversal is unambiguous.
- Prefer invalidation when overlapping optimistic writes complicate rollback.
Streaming cache updates
Subscribe to server events for a cache entry and clean up when its lifecycle ends.
- Open the stream from the cache-entry lifecycle handler.
- Apply incoming changes through updateCachedData.
- Close external subscriptions when cacheEntryRemoved resolves.
Pagination and infinite data
Model pages and arguments so cached results do not overwrite unrelated query states.
- Include filters and page identity in query arguments.
- Define page merging and refresh behavior deliberately.
- Avoid mixing results from different searches into one list.
Authentication and reauthorization
Centralize credential handling and coordinate refresh behavior across failed requests.
- Attach credentials through centralized request configuration.
- Coordinate refresh attempts to avoid parallel token-refresh storms.
- Retry the original request only after successful reauthorization.
Code splitting and endpoint injection
Extend an API slice without creating unnecessary isolated caches.
- Inject feature endpoints into a shared API slice.
- Keep a common base URL and cache tag vocabulary.
- Export hooks from the extended API returned by injection.
Sources
- Redux Toolkit official documentation