< Zpět na články

Možnosti změny cache v Tanstack Query

Martin MacuraMartin Macura
09. července 2024

Tanstack Query je super, má spoustu skvělých features – jednou z nich je to, že se výsledky queries cachují. Co když ale potřebuju něco v cachi změnit? Jaké jsou možnosti a kdy se každá hodí? A co to vůbec znamená, že mám stará data?

Co je to Tanstack Query?

Tanstack Query (dříve také známé jako React Query) je populární knihovna pro správu asynchronních dat (tzv. query). Její nejčastější použití je na orchestraci stahování dat z API (nejen) v React aplikacích – vystavuje přívětivé API, data cachuje, umožňuje zkoušet stahovat data znovu, pokud se při stahování něco pokazilo, a většina aplikací si vystačí s defaultní konfigurací. Také umožňuje spravovat mutace – tedy asynchronní změny, u nich opět nabízí pohodlné API, díky kterému lze lehce deklarovat např. různé side-effects změny. To celé doplňuje svými DeveloperTools, ve kterých si můžeme zobrazit stav všech spuštěných queries v aplikaci a případně jejich stav měnit pro debugging.

Příklad query a mutace může vypadat například takto:

const {data, isPending ,error} = useQuery({
   queryKey: ["users"],
   queryFn: async () => {
       const resp = await fetch("https://example.com/api/users");
       // TODO check response
       return resp.json();
   }
});


const {mutate: addUser} = useMutation({
   mutationFn: async (newUser) => {
       const resp = await fetch("https://example.com/api/users", {
           method: "POST",
           headers: {"Content-Type": "application/json"},
           body: JSON.stringify(newUser)
       });
       // TODO check response
       return resp.json()
   },
   onSuccess: (data) => {
       toast("User created", "success");
       redirect("/users/" + data.id);
   },
   onError: (e) => {
       toast("Something went wrong", "error");
       logger.error(e);
   }
})

Změna cache v Tanstack Query

Představme si následující situaci: ze serveru jsme stáhli seznam uživatelů, které následně zobrazujeme na stránce. Jelikož jsme použili Tanstack Query, data se nám cachují a jsou tedy stále připravena, i když v aplikaci například přejdeme na jinou stránku a pak se vrátíme. Poté přidáme nového uživatele pomocí požadavku na server, co ale s těmi daty v cachi?

Tanstack Query nám dává k dispozici objekt QueryClient, na kterém můžeme volat několik metod pro správu cache, každá se hodí na něco jiného. U většiny si můžeme volit, jestli je chceme aplikovat na všechny queries nebo jen některé.

Invalidace (QueryClient.invalidateQueries)

Invalidace je asi nejčastější operací s cachí, označí queries za “stale” (tedy, že má zastaralá data) a aktivní queries se pokusí stáhnout znovu. Dokud se ale nová data nestáhnou, stále zobrazuje ta stará. Zpět vrací promise, který se resolvene, až skončí proces refetchování.

💡 Aktivní queries jsou ty, které se nacházejí v aktuálně vyrenderované komponentě.

Tohle chování se podle mě hodí, pokud se jedná o data, u kterých nevadí, když je uživatel neuvidí ihned aktuální nebo u nich nepotřebujeme indikátor načítání.

Smazání (QueryClient.removeQueries)

Smazání způsobí, že TanstackQuery na queries “zapomene”. Neaktivní queries o svá data příjdou a po vyrenderování si je musí získat znovu, aktivní queries si stále svá data “pamatují”, dokud se nepřerenderují. Tohle mi připadá vhodné při operacích, kdy uživatel v aplikaci žádná data vidět nemá – tím může být například odhlášení, někdy to může dávat smysl třeba při změně jazyka.

Resetování (QueryClient.resetQueries)

Resetování je podobné smazání, ale smaže jen data, všechny queries si stále pamatuje a ty aktivní upozorní, že už jejich data nemá a mají se je tedy pokusit data znovu získat. Toto mi připadá ideální pro případy, kdy se jedná o velkou změnu – například uživatel upgraduje svůj účet na jinou úroveň, která mu umožňuje nové operace nebo jinak mění prvky na stránce.

Nastavení dat (QueryClient.setQueryData)

Nastavení dat můžeme využívat v případech, kdy na stav query umíme přijít jinak než novým “výpočtem”. Tím mohou být případy, kdy nám server po úpravě záznamu nový záznam vrátí, očekávaná hodnota je primitivní (např. mutace schování banneru, který se zobrazuje na základě booleanovské query) nebo pro jiné optimistické mutace.

⚠️ Často bývá dobrou praktikou tuto metodu kombinovat s invalidací, instantně zobrazíme očekávaná data a jakmile získáme ty pravá, tak zobrazíme je. Navíc pokud bychom měli v mutaci bug, přijdeme na něj hned po získání pravých dat, která nebudou stejná jako ta očekávaná.

Další metody

Stale queries

Queries se zastaralými daty jsou automaticky refreshnuty, pokud se znovu využijí (mountnou) nebo nebo uživatel například opustí okno a opět se vrátí. Jak dlouho jsou data z query považována za čerstvá (fresh), lze nastavit, defaultně je to ale 0 ms.

Shrnutí: Možnosti změny cache v Tanstack Query

Ukázali jsme si, jak různě manipulovat s cache v Tanstack Query. Taky jsme si ukázali rozdíly v přístupech a popsali, kdy se může co hodit. Kdybyste si to chtěli vyzkoušet, můžete mrknout na demo projekt, který je i nasazený, pokud ho nechcete spouštět u sebe.

ℹ️Určitě ještě stojí za zmínku, že většina metod umožňuje rozsáhlou customizaci a popsané chování platí primárně pro defaultní nastavení.

Jak pracujete s cachí vy? Používáte metody jinak než my, nebo dokonce používáte něco jiného než Tanstack Query? Dejte nám o tom vědět třeba na Twitteru.

Zdroje: Tanstack Query Demo projekt Demo projekt

Martin Macura
Martin Macura
Frontend DeveloperMartin rád vybírá divná místa na práci, vedle front-endu ho baví celý full-stack vývoj a vzdělávání sebe i ostatních. Kromě práce má rád hudbu, špatné vtípky a “občasný” kebab.

Máte zájem o spolupráci? Pojďme to probrat osobně!

Napište nám >