Cache Apollo: normalizacja i aktualizacje
Zrozumieć znormalizowany InMemoryCache Apollo i aktualizować dane w cache po mutacjach bez ponownego pobierania
Cache Apollo: normalizacja i aktualizacje to bezpłatna lekcja React Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej React Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs React Academy zawiera 4 lekcji w sumie.
Jak InMemoryCache normalizuje dane
InMemoryCache przechowuje każdy obiekt pod kluczem pamięci podręcznej złożonym z __typename i id: User:1, Post:42. Gdy zapytanie zwraca obiekt User z id "1", jest on przechowywany tylko raz pod tym kluczem, niezależnie od liczby różnych zapytań, które go zawierają.
Każde kolejne zapytanie pobierające ten sam obiekt User:1 odczytuje dane z jednego wpisu pamięci podręcznej, dzięki czemu wszystkie komponenty widzą te same dane.
Automatyczne aktualizacje między zapytaniami
Gdy mutacja zwraca zaktualizowany obiekt User:1, Apollo zapisuje go we wpisie pamięci podręcznej User:1. Każde aktywne zapytanie, które zawierało User:1, automatycznie odzwierciedla zaktualizowane pola w interfejsie użytkownika bez dodatkowego kodu.
Ta automatyczna propagacja jest główną przewagą znormalizowanej pamięci podręcznej nad pamięcią podręczną opartą na dokumentach (kluczach zapytań).
cache.readQuery
Odczytuje bieżący wynik zapytania zapisany w pamięci podręcznej: cache.readQuery({ query: GET_USERS }) zwraca obiekt danych tak, jakby został zwrócony przez useQuery. Zwraca null, jeśli zapytania nie ma w pamięci podręcznej.
Należy używać readQuery wewnątrz funkcji aktualizujących mutację, aby odczytać bieżącą listę przed jej modyfikacją.
cache.writeQuery
cache.writeQuery({ query: GET_USERS, data: { users: updatedUsers } }) zapisuje dane bezpośrednio w pamięci podręcznej, wywołując ponowne renderowanie we wszystkich komponentach odczytujących GET_USERS. Żadne żądanie sieciowe nie jest wykonywane.
Połączenie readQuery i writeQuery pozwala implementować niemutowalne aktualizacje pamięci podręcznej: odczytać dane, utworzyć nową tablicę i zapisać ją ponownie.
cache.modify do bezpośredniej aktualizacji encji
cache.modify({ id: cache.identify(user), fields: { name: () => 'New Name' } }) bezpośrednio modyfikuje pola określonej encji zapisanej w pamięci podręcznej. Nie trzeba najpierw odczytywać zapytania, jeśli znają Państwo identyfikator encji w pamięci podręcznej.
Obiekt fields mapuje nazwy pól na funkcje modyfikujące, które otrzymują bieżącą wartość i zwracają nową wartość.
Aktualizowanie pamięci podręcznej po mutacji
Do useMutation należy przekazać funkcję update: useMutation(ADD_POST, { update(cache, { data: { addPost } }) { cache.modify({ id: cache.identify(user), fields: { posts: existingPosts => [...existingPosts, addPost] } }); } }).
Dodaje to nowy post na końcu tablicy postów użytkownika zapisanej w pamięci podręcznej, aktualizując wszystkie komponenty wyświetlające listę postów użytkownika.
cache.evict: usuwanie wpisów pamięci podręcznej
cache.evict({ id: 'User:1' }) usuwa wpis User:1 z pamięci podręcznej. Każde aktywne zapytanie, które zawierało User:1, zostanie ponownie wyrenderowane bez tej encji w wyniku.
Po usunięciu wpisów należy wywołać cache.gc(), aby usunąć obiekty, do których nie można już dotrzeć z poziomu zapytań głównych. Zapobiega to wyciekom pamięci w długo działających aplikacjach.
Zbieranie nieużywanych obiektów
cache.gc() przechodzi przez graf pamięci podręcznej, zaczynając od wszystkich aktywnych zapytań, i usuwa encje, do których nie można już dotrzeć. Można bezpiecznie wywoływać tę funkcję okresowo lub po wykonaniu zbiorczych mutacji usuwających wiele encji.
Encje wskazywane przez aktywne hooki useQuery nigdy nie są usuwane przez mechanizm garbage collection; usuwane są wyłącznie osierocone encje, które nie należą już do żadnego wyniku zapytania.
Przekierowania pamięci podręcznej za pomocą zasad pól
Jeśli wysyłają Państwo zapytanie o pojedynczą encję (GET_USER według id), która jest już zapisana jako część wyniku zapytania o listę, Apollo może odczytać ją z pamięci podręcznej bez dodatkowego żądania sieciowego. Służą do tego zasady pól: keyArgs i funkcje read w zasadach typu.
Funkcja read zwraca odwołanie do pamięci podręcznej: return toReference({ __typename: 'User', id: args.id }), informując Apollo, aby odczytał dane z istniejącego wpisu User:id w pamięci podręcznej.
Niestandardowe keyFields dla niestandardowych identyfikatorów
Jeśli encje używają pola innego niż id jako unikatowego klucza (np. slug lub uuid), należy skonfigurować je w zasadach typu: new InMemoryCache({ typePolicies: { Post: { keyFields: ['slug'] } } }).
Wówczas Apollo używa Post:my-post-slug jako klucza pamięci podręcznej zamiast wymagać pola id, zachowując normalizację w przypadku schematów o niestandardowej strukturze.
refetchQueries a funkcja update
refetchQueries: [{ query: GET_USERS }] w opcjach useMutation wywołuje ponowne pobranie danych z sieci po zakończeniu mutacji. To prostsze rozwiązanie, ale zawsze wykonuje żądanie sieciowe.
Funkcja update modyfikuje pamięć podręczną lokalnie i unika dodatkowego żądania sieciowego. Należy użyć refetchQueries, gdy logika aktualizacji pamięci podręcznej jest zbyt złożona, aby ją napisać, lub gdy pola obliczane przez serwer sprawiają, że lokalne aktualizacje pamięci podręcznej są niewiarygodne.
Klucz normalizacji InMemoryCache
Jaki jest domyślny format klucza pamięci podręcznej używany przez InMemoryCache do przechowywania encji?
Podsumowanie lekcji
InMemoryCache normalizuje encje za pomocą __typename+id, umożliwiając automatyczne aktualizacje między zapytaniami. Pamięcią podręczną można zarządzać za pomocą cache.readQuery, cache.writeQuery i cache.modify. Encje należy usuwać za pomocą cache.evict, a następnie cache.gc. Niestandardowe pola klucza konfiguruje się przez typePolicies w przypadku kluczy głównych innych niż id.
Funkcji aktualizujących mutację należy używać dla wydajnych lokalnych aktualizacji pamięci podręcznej; refetchQueries należy stosować, gdy pola obliczane przez serwer sprawiają, że lokalne aktualizacje są niewiarygodne.
Często zadawane pytania
Czy lekcja „Cache Apollo: normalizacja i aktualizacje” jest bezpłatna?
Tak — pełny tekst „Cache Apollo: normalizacja i aktualizacje” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu React Academy, przejdź na CoddyKit PRO. Kurs React Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Cache Apollo: normalizacja i aktualizacje”?
Zrozumieć znormalizowany InMemoryCache Apollo i aktualizować dane w cache po mutacjach bez ponownego pobierania Ćwiczysz React Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć React Academy?
Nie wymagamy żadnego doświadczenia. React Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.
Ile czasu zajmuje lekcja „Cache Apollo: normalizacja i aktualizacje”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji React Academy?
Tak. Każda lekcja React Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Podstawy GraphQL dla programistów Reacta
- Konfiguracja Apollo Client w React
- Hooki useQuery i useMutation
- Cache Apollo: normalizacja i aktualizacje