Offline React Query

Řekl jsem to znovu a znovu - React Query je správce asynchronního stavu. Dokud tomu dáte Slib, vyřešený nebo zamítnutý, knihovna je šťastná. Nezáleží na tom, odkud tento slib pochází.

Existuje mnoho způsobů, jak vytvářet sliby, ale zdaleka největším případem použití je získávání dat. Velmi často to vyžaduje aktivní síťové připojení. Někdy však, zejména na mobilních zařízeních, kde může být připojení k síti nespolehlivé, potřebujete, aby aplikace fungovala i bez něj.

Problémy ve verzi 3

React Query je velmi dobře vybaven pro zpracování offline scénářů. Protože poskytuje vrstvu mezipaměti, pokud je mezipaměť plná, můžete pokračovat v práci, i když nemáte připojení k síti. Podívejme se na několik okrajových scénářů, kde v3 nebude fungovat podle očekávání. Pro ilustraci použiji náš základní příklad seznamu příspěvků / podrobností příspěvku z dokumentů:

1) žádná data v mezipaměti

Jak jsem řekl, ve verzi 3 věci fungují dobře, pokud je mezipaměť plná. Okrajový případ, kdy se věci stanou divnými, by byl následující:

  • Máte dobré připojení k síti a přejděte do zobrazení seznamu
  • Ztratíte spojení a kliknete na příspěvek.

Stane se, že váš dotaz zůstane v načítání stav, dokud znovu nezískáte připojení. Také můžete vidět neúspěšný síťový požadavek v devtools prohlížeče. Je to proto, že React Query vždy spustí první požadavek, a pokud selže, pozastaví pokusy, pokud nemáte připojení k síti.

Nástroj React Query Devtools dále ukáže, že se váš dotaz načítá , což není tak úplně pravda. Dotaz je ve skutečnosti pozastaven , ale nemáme žádný koncept, který by tento stav reprezentoval – je to skrytý detail implementace.

2) žádné opakování

Podobně, pokud jste ve výše uvedeném scénáři úplně vypnuli opakování, váš dotaz přejde okamžitě do chybového stavu, bez možnosti to zastavit.

Proč potřebuji opakování aby se můj dotaz pozastavil pokud nemám připojení k síti 🤷‍♂️?

3) dotazy, které nepotřebují síť

Dotazy, které ke své práci nepotřebují síťové připojení (např. protože provádějí drahé asynchronní zpracování ve webovém pracovníkovi), budou pozastaveny, dokud znovu nezískáte síťové připojení, pokud z nějakého jiného důvodu selžou. Tyto dotazy se také nespustí při fokusu okna, protože tato funkce je zcela zakázána, pokud nemáte připojení k síti.

Stručně řečeno, existují dva hlavní problémy:V některých případech React Query předpokládá, že je potřeba síťové připojení, když to nemusí být pravda (případ 3), a v jiných případech React Query spustí dotaz, i když by pravděpodobně neměl. (případy 1 a 2).

Nový síťový režim

Ve verzi 4 jsme se pokusili tento problém řešit holisticky pomocí nového networkMode nastavení. Díky tomu můžeme jasně rozlišovat mezi online a offline dotazy. Je to volba pro useQuery stejně jako useMutation , což znamená, že jej můžete nastavit globálně nebo na základě dotazu. Koneckonců, můžete mít některé dotazy, které vyžadují připojení k síti, a některé ne.

online

Toto je nový výchozí režim ve verzi 4, protože očekáváme, že většina uživatelů bude používat React Query v kombinaci s načítáním dat. Stručně řečeno, s tímto nastavením předpokládáme, že dotaz lze spustit pouze v případě, že má aktivní síťové připojení.

Co se tedy stane, když chcete spustit dotaz, který vyžaduje síťové připojení, když žádné nemáte? Dotaz přejde na nový pozastaven Stát. To pozastaveno stav je sekundární k hlavnímu stavu, ve kterém může být dotaz:idle , načítání , úspěch nebo chyba , protože připojení k síti můžete kdykoli ztratit.

To znamená, že můžete být úspěšní stav a pozastaveno , například pokud jste jednou úspěšně načetli data, ale opětovné načítání na pozadí bylo pozastaveno.

Nebo můžete být v režimu načítání stav a pozastaveno pokud se dotaz připojí poprvé.

fetchStatus

Vždy jsme měli isFetching příznak, který indikoval, že byl spuštěn dotaz. Podobné jako nové pozastaveno stavu, může být dotaz úspěšný a načítání , nebo to může být chyba a načítání . Načtení na pozadí vám dají hodně z možných stavů, ve kterých se mají nacházet (👋 stavové automaty).

Jako načítání a pozastaveno se vzájemně vylučují, spojili jsme je do nového fetchStatus který se nyní vrací z useQuery :

  • fetching :Dotaz se skutečně provádí – požadavek probíhá.
  • paused :Dotaz se neprovádí – je pozastaven, dokud znovu nezískáte připojení.
  • idle :Dotaz momentálně není spuštěn.

Obecně platí, že stav dotazu vám poskytne informace o datech :úspěch znamená, že budete mít data vždy, načítání znamená, že ještě nemáte data. Přemýšlel jsem o přejmenování načítání stav nevyřízeno , ale bohužel, to by bylo pravděpodobně "příliš zlomové". 😅

Na druhé straně fetchStatus poskytuje informace o queryFn :běží nebo ne? isFetching a isPaused příznaky jsou odvozeny od tohoto stavu.

Pojďme se podívat, jak může vypadat případ 1 shora ve v4. Všimněte si nového tlačítka pro přepínání režimu sítě v nástrojích RQ devtools. Je to docela fajn, protože to ve skutečnosti nevypíná vaši síť – jen to React Query věří že neexistuje síť pro testovací účely. Ano, jsem na to docela hrdý. 😊

Jasně vidíme, v jakém stavu se dotaz nachází (pozastaveno ) kvůli novému fialovému odznaku stavu. První síťový požadavek je také proveden, jakmile síť znovu zapneme.

vždy

V tomto režimu se React Query vůbec nestará o vaše síťové připojení. Dotazy budou vždy spuštěny a nikdy nebudou pozastaveny. To je nejužitečnější, pokud používáte React Query pro něco jiného než načítání dat.

nejprve offline

Tento režim je velmi podobný tomu, jak fungoval React Query ve verzi 3. První požadavek bude vždy a pokud se to nezdaří, opakované pokusy budou pozastaveny. Tento režim je užitečný, pokud používáte další vrstvu mezipaměti, jako je mezipaměť prohlížeče nad React Query.

Vezměme si jako příklad GitHub repo API. Odešle následující hlavičky odpovědí:

cache-control: public, max-age=60, s-maxage=60

což znamená, že po dobu dalších 60 sekund, pokud o tento zdroj požádáte znovu, bude odpověď pocházet z mezipaměti prohlížeče. Skvělé na tom je, že to funguje, i když jste offline! Pracovníci obsluhy, např. pro offline první PWA fungují podobně tak, že zachytí síťový požadavek a doručí odpovědi uložené v mezipaměti, pokud jsou dostupné.

Nyní by tyto věci nefungovaly, pokud by se React Query rozhodlo ne spusťte požadavek, protože nemáte připojení k síti, jako je výchozí online režim ano. Chcete-li zachytit požadavek na načtení, musí k tomu dojít :) Pokud tedy máte tuto další vrstvu mezipaměti, nezapomeňte použít offlineFirst režim sítě .

Pokud první požadavek vyjde a vy narazíte na mezipaměť – skvělé, váš dotaz bude úspěšný stavu a získáte tato data. A pokud dojde k chybě mezipaměti, pravděpodobně se zobrazí chyba sítě, po které React Query pozastaví pokusy, čímž se váš dotaz přesune do pole pozastaveno Stát. Je to to nejlepší z obou světů. 🙌

Co to všechno pro mě přesně znamená?

Nic, pokud nechceš. Stále se můžete rozhodnout ignorovat tento nový fetchStatus a zkontrolujte pouze isLoading - React Query se bude chovat stejně jako předtím (dobře - případ 2 shora bude fungovat lépe, protože neuvidíte chybu sítě).

Pokud je však pro vás prioritou učinit vaši aplikaci robustní pro situace, kdy nemáte připojení k síti, máte nyní možnost reagovat na vystavený fetchStatus a podle toho jednat.

Je jen na vás, co s tímto novým stavem uděláte. Jsem nadšený, až uvidím, kteří ux lidé na tom budou stavět. 🚀

To je pro dnešek vše. Neváhejte mě kontaktovat na twitteru
pokud máte nějaké dotazy, nebo zanechte komentář níže ⬇️