Implement data fetching and caching in React Native apps using RTK Query with Redux Toolkit. Use when working with APIs, REST endpoints, data fetching, caching, mutations, or when the user mentions RTK Query, Redux Toolkit, or API integration in React Native.
RTK Query is Redux Toolkit's powerful data fetching and caching tool. This skill guides you through implementing efficient API integration in React Native applications.
RTK Query automates:
Location: src/services/api.ts or src/store/api/[featureName]Api.ts
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react';
export const api = createApi({
reducerPath: 'api',
baseQuery: fetchBaseQuery({
baseUrl: 'https://your-api.com/api',
prepareHeaders: (headers, { getState }) => {
// Add auth token if available
const token = (getState() as RootState).auth.token;
if (token) {
headers.set('authorization', `Bearer ${token}`);
}
return headers;
},
}),
tagTypes: ['User', 'Asset', 'Category'],
endpoints: (builder) => ({}),
});
Add endpoints using builder.query for GET and builder.mutation for POST/PUT/DELETE:
export const userApi = api.injectEndpoints({
endpoints: (builder) => ({
// Query (GET)
getUsers: builder.query<User[], void>({
query: () => '/users',
providesTags: ['User'],
}),
// Query with params
getUserById: builder.query<User, string>({
query: (id) => `/users/${id}`,
providesTags: (result, error, id) => [{ type: 'User', id }],
}),
// Mutation (POST/PUT/DELETE)
createUser: builder.mutation<User, Partial<User>>({
query: (newUser) => ({
url: '/users',
method: 'POST',
body: newUser,
}),
invalidatesTags: ['User'],
}),
// Update mutation
updateUser: builder.mutation<User, { id: string; data: Partial<User> }>({
query: ({ id, data }) => ({
url: `/users/${id}`,
method: 'PUT',
body: data,
}),
invalidatesTags: (result, error, { id }) => [{ type: 'User', id }],
}),
// Delete mutation
deleteUser: builder.mutation<void, string>({
query: (id) => ({
url: `/users/${id}`,
method: 'DELETE',
}),
invalidatesTags: ['User'],
}),
}),
});
export const {
useGetUsersQuery,
useGetUserByIdQuery,
useCreateUserMutation,
useUpdateUserMutation,
useDeleteUserMutation,
} = userApi;
Location: src/store/store.ts
import { configureStore } from '@reduxjs/toolkit';
import { api } from './api';
export const store = configureStore({
reducer: {
[api.reducerPath]: api.reducer,
// other reducers...
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(api.middleware),
});
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;
import React from 'react';
import { View, Text, FlatList, ActivityIndicator } from 'react-native';
import { useGetUsersQuery } from '../services/userApi';
export const UserListScreen = () => {
const { data: users, isLoading, isError, error, refetch } = useGetUsersQuery();
if (isLoading) {
return <ActivityIndicator size="large" />;
}
if (isError) {
return <Text>Error: {error.message}</Text>;
}
return (
<FlatList
data={users}
keyExtractor={(item) => item.id}
renderItem={({ item }) => <Text>{item.name}</Text>}
onRefresh={refetch}
refreshing={isLoading}
/>
);
};
Tags create relationships between queries and mutations: