QueryClient, QueryClientProvider och useQuery
Konfigurera TanStack Query med en QueryClient, omslut appen med QueryClientProvider och hämta data med useQuery – i stället för manuell hämtning baserad på useEffect.
QueryClient, QueryClientProvider och useQuery är en gratis lektion i React Native Academy på CoddyKit. Detta är lektion 1 av 4. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för React Native Academy, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i React Native Academy innehåller totalt 4 lektioner.
Vad är TanStack React Query?
TanStack React Query (tidigare React Query) är ett bibliotek för datahämtning och cachning som hanterar serverstatus i er React Native-app. I stället för att manuellt hantera status för inläsning, fel och data med useState och useEffect erbjuder React Query smart cachning, hämtning i bakgrunden och automatiska nya försök — allt via ett enkelt hook-API.
Serverstatus skiljer sig i grunden från UI-status: den finns på en fjärrserver, kan vara inaktuell, behöver hämtas på nytt och kan behövas av flera komponenter. React Query löser allt detta på ett väl beprövat och produktionsdokumenterat sätt.
// Traditional approach (before React Query):
const [data, setData] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
// With React Query:
const { data, isLoading, error } = useQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
});
// Same result — dramatically less codeInstallera TanStack Query
Installera TanStack Query (v5) och insticksprogrammet för beständig lagring som är specifikt för React Native. Kärnpaketet är @tanstack/react-query. I Expo-projekt kan ni även vilja använda utvecklarverktygen, men de kräver en webbläsarmiljö för visning.
React Query v5 använder objektsyntax för hook-alternativ (en brytande förändring jämfört med v4). Om ni ser handledningar som använder positionsargument för useQuery gäller de v4. Den här lektionen behandlar det moderna v5-API:t.
// Install:
// npx expo install @tanstack/react-query
// npx expo install @tanstack/react-query-persist-client
// npx expo install @tanstack/async-storage-persister
// npx expo install @react-native-async-storage/async-storage
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';Konfigurera QueryClient
QueryClient är kärnobjektet som hanterar alla cachar, frågor och mutationer. Skapa en instans och dela den i hela appen. Konfigurera globala standardvärden i konstruktorn för QueryClient — de gäller för alla frågor om de inte åsidosätts på den enskilda frågenivån.
Skapa QueryClient utanför komponentträdet (eller i en useState-initierare) så att den inte skapas på nytt vid varje rendering. En återskapad QueryClient förlorar all cachad data.
import { QueryClient } from '@tanstack/react-query';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 5 * 60 * 1000, // 5 minutes before considered stale
gcTime: 10 * 60 * 1000, // 10 minutes before garbage collected
retry: 2, // retry failed requests twice
refetchOnWindowFocus: false, // disable for mobile
},
},
});QueryClientProvider: gör klienten tillgänglig
Omslut appens rot med QueryClientProvider och skicka QueryClient-instansen som egenskapen client. Alla komponenter inuti providern kan då komma åt QueryClient och använda React Query-hookar. Detta liknar React Reduxs Provider eller React Navigations NavigationContainer.
Placera QueryClientProvider längst upp i appen så att navigation och andra providers omsluts. Ordningen tillsammans med andra providers (som Redux Provider eller AuthProvider) spelar vanligtvis ingen roll, såvida de inte är beroende av varandra.
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient({
defaultOptions: { queries: { staleTime: 5 * 60 * 1000 } },
});
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<NavigationContainer>
<RootNavigator />
</NavigationContainer>
</QueryClientProvider>
);
}useQuery: hämta data
useQuery är den primära hooken för att hämta och cacha serverdata. Den tar ett konfigurationsobjekt med två obligatoriska fält: queryKey (en unik identifierare för datan) och queryFn (den asynkrona funktionen som hämtar datan). React Query anropar queryFn automatiskt och cachar resultatet.
Hooken returnerar data, isLoading, isFetching, error och många andra statusvärden. isLoading är true vid den första inläsningen; isFetching är true när en hämtning pågår, även vid hämtning i bakgrunden.
import { useQuery } from '@tanstack/react-query';
async function fetchPosts() {
const response = await fetch('https://api.example.com/posts');
if (!response.ok) throw new Error('Network error');
return response.json();
}
function PostsScreen() {
const { data, isLoading, error } = useQuery({
queryKey: ['posts'],
queryFn: fetchPosts,
});
if (isLoading) return <ActivityIndicator />;
if (error) return <Text>Error: {error.message}</Text>;
return <FlatList data={data} renderItem={...} />;
}Frågenycklar: cachens identitet
queryKey anger hur React Query identifierar och återanvänder cachad data. Använd en array som innehåller datatypen och alla variabler som hämtningen beror på. Frågor med samma nyckel delar cachad data — flera komponenter som använder ['posts'] hämtar bara en gång och delar samma dataobjekt.
Ta med dynamiska parametrar i nyckelarrayen så att olika parameterkombinationer får separata cacheposter. Exempelvis cachar ['user', userId] varje användares data separat. Nycklar jämförs efter värde (djup jämförelse), inte efter referens.
// Static key:
const { data: posts } = useQuery({
queryKey: ['posts'],
queryFn: fetchAllPosts,
});
// Dynamic key — separate cache per user:
const { data: user } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetchUser(userId),
});
// Compound key with filters:
const { data: filteredPosts } = useQuery({
queryKey: ['posts', { status: 'published', category: 'tech' }],
queryFn: () => fetchPosts({ status: 'published', category: 'tech' }),
});staleTime och cacheTime
staleTime avgör hur länge cachad data anses vara aktuell innan React Query hämtar aktuell data i bakgrunden. Under den tiden returneras det cachade värdet direkt utan någon nätverksförfrågan. Efter staleTime betraktas datan som inaktuell och en ny hämtning i bakgrunden startas vid nästa montering eller när fönstret får fokus.
gcTime (tidigare cacheTime) avgör hur länge oanvända cacheposter (utan observatörer) behålls i minnet innan de rensas bort. Cachen finns kvar även efter att alla komponenter som använder den har avmonterats, tills gcTime löper ut.
const { data } = useQuery({
queryKey: ['settings'],
queryFn: fetchUserSettings,
staleTime: 10 * 60 * 1000, // fresh for 10 min, no background refetch
gcTime: 30 * 60 * 1000, // kept in cache for 30 min after unmount
});
// Infinity means never stale (manual invalidation only):
const { data: config } = useQuery({
queryKey: ['app-config'],
queryFn: fetchAppConfig,
staleTime: Infinity,
});Beroende frågor
Vissa frågor är beroende av data från en annan fråga. Använd alternativet enabled för att inaktivera en fråga tills dess beroende är redo. React Query anropar inte queryFn när enabled är false och börjar automatiskt hämta data när enabled blir true.
Detta ersätter kedjor av kapslade useEffect där ni väntar på att en hämtning ska slutföras innan en annan startas. Mönstret med beroende frågor är deklarativt och enklare att förstå.
// Fetch user first:
const { data: user } = useQuery({
queryKey: ['user', userId],
queryFn: () => fetchUser(userId),
});
// Then fetch user's posts when user is available:
const { data: userPosts } = useQuery({
queryKey: ['posts', user?.id],
queryFn: () => fetchUserPosts(user.id),
enabled: !!user, // only runs after user is fetched
});Beteende vid nya försök och felhantering
React Query försöker automatiskt igen med exponentiell backoff när frågor misslyckas. Standardvärdet är 3 försök. Konfigurera retry (antal) och retryDelay (ms eller funktion) per fråga. När alla försök har misslyckats fylls fältet error i och isError blir true.
queryFn måste kasta ett fel för att signalera ett misslyckande — att returnera null eller ett särskilt felobjekt utlöser inte ett nytt försök. Kasta alltid ett fel i frågefunktionen när svaret anger ett fel (kontrollera HTTP-statuskoder uttryckligen).
const { data, isError, error } = useQuery({
queryKey: ['data'],
queryFn: async () => {
const res = await fetch('https://api.example.com/data');
if (!res.ok) {
throw new Error('Request failed: ' + res.status); // must throw!
}
return res.json();
},
retry: 3,
retryDelay: (attempt) => Math.min(1000 * 2 ** attempt, 30000),
});Manuell ogiltigförklaring av frågor
När ni vet att data på servern har ändrats (till exempel efter en mutation) kan ni ogiltigförklara de relevanta frågorna med queryClient.invalidateQueries({ queryKey: ['posts'] }). Då markeras den cachade datan som inaktuell och en bakgrundshämtning utlöses för de komponenter som för närvarande observerar frågan.
Att ogiltigförklara frågor är ett av de kraftfullaste mönstren i React Query — efter att en ny kommentar har skickats kan ni ogiltigförklara kommentarsfrågan, så uppdateras listan automatiskt. Ingen manuell tillståndsuppdatering behövs.
import { useQueryClient } from '@tanstack/react-query';
function PostButton() {
const queryClient = useQueryClient();
async function handlePost() {
await submitPost(newPostData);
// Invalidate posts list — triggers background refetch:
await queryClient.invalidateQueries({ queryKey: ['posts'] });
}
}Bakgrundshämtning när appen får fokus
React Query kan automatiskt hämta inaktuell data på nytt när användaren återgår till appen från bakgrunden. På webben används window focus; i React Native behöver ni konfigurera detta med focusManager och AppState. På så sätt hålls datan automatiskt uppdaterad utan att användaren behöver uppdatera manuellt.
Konfigurera fokusansvarig en gång när appen startar. Därefter hämtas alla inaktuella frågor automatiskt på nytt när användaren växlar tillbaka till appen, så att gränssnittet hålls aktuellt utan ytterligare kod i enskilda komponenter.
import { focusManager } from '@tanstack/react-query';
import { AppState } from 'react-native';
// At app startup (App.js or index.js):
AppState.addEventListener('change', (state) => {
focusManager.setFocused(state === 'active');
});
// Queries with staleTime < Infinity will refetch
// automatically when app comes to foregroundSnabbkontroll
Testa era kunskaper om koncepten inom React Native Mobile Development från den här lektionen.
Sammanfattning av lektionen
I den här lektionen har ni lärt er att QueryClient innehåller cachen och tillhandahålls till komponentträdet via QueryClientProvider, att useQuery hämtar och cachar serverdata som identifieras av queryKey och automatiskt anropar queryFn, samt att staleTime styr hur länge cachad data betraktas som färsk innan en bakgrundshämtning utlöses. Nästa steg är att använda useMutation för att ändra serverdata och automatiskt uppdatera relaterade frågor.
Lär dig JavaScript med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 30
- Lektioner
- 120
Vanliga frågor
Är lektionen ”QueryClient, QueryClientProvider och useQuery” gratis?
Ja – du kan läsa vilka 3 lektioner som helst i lärvägen React Native Academy, inklusive ”QueryClient, QueryClientProvider och useQuery”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i React Native Academy innehåller totalt 4 lektioner.
Vad lär jag mig i ”QueryClient, QueryClientProvider och useQuery”?
Konfigurera TanStack Query med en QueryClient, omslut appen med QueryClientProvider och hämta data med useQuery – i stället för manuell hämtning baserad på useEffect. Ni övar på React Native Academy med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig React Native Academy?
Du behöver inga förkunskaper. Utbildningen i React Native Academy på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.
Hur lång tid tar lektionen ”QueryClient, QueryClientProvider och useQuery”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här React Native Academy-lektionen?
Ja. Varje React Native Academy-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- QueryClient, QueryClientProvider och useQuery
- Mutationer med useMutation och cacheinvalidering
- Beständiggöra frågecachen med AsyncStorage
- Konfigurera bakgrundshämtning och stale time