Mutaatiot useMutationilla ja välimuistin mitätöinti
Käyttäkää useMutationia tietojen POST-lähetykseen, mitätöikää liittyvät kyselyt onnistumisen jälkeen, jotta luettelo päivittyy automaattisesti, ja näyttäkää optimistinen käyttöliittymäpalaute pyynnön ollessa käynnissä.
Mutaatiot useMutationilla ja välimuistin mitätöinti on ilmainen React Native Academy-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea tästä oppimispolusta kokonaan mitkä tahansa 3 oppituntia ilmaiseksi — sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä käytännön harjoittelun sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. Oppitunti kuuluu React Native Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. React Native Academy-kurssilla on yhteensä 4 oppituntia.
Mikä on mutaatio?
React Queryn terminologiassa mutaatio tarkoittaa mitä tahansa palvelindataa muuttavaa toimintoa — POST-, PUT-, PATCH- tai DELETE-pyyntöä. Siinä missä useQuery noutaa ja tallentaa dataa välimuistiin, useMutation käsittelee datan muokkaamista ja tarjoaa lataus-, virhe- ja onnistumistilat sekä tehokkaat sivuvaikutusten käsittelyyn tarkoitetut callback-funktiot.
Kyselyiden (lukujen) ja mutaatioiden (kirjoitusten) erottaminen on keskeinen käsitteellinen toimintamalli. Mutaatiot eivät tallenna tuloksiaan välimuistiin, vaan käynnistävät sivuvaikutuksia ja saavat sen jälkeen asiaankuuluvat kyselyt hakemaan tuoreen datan uudelleen.
useMutationin perusteet
useMutation saa parametrikseen mutationFn-funktion — asynkronisen funktion, joka suorittaa kirjoitusoperaation. Se palauttaa mutate-funktion (tai Promise-pohjaiseen käyttöön mutateAsync-funktion), jota kutsutaan, kun käyttäjä käynnistää toiminnon.
Toisin kuin useQuery, mutaatiot eivät käynnisty automaattisesti. Ne odottavat, että kutsutte mutate(variables)-funktiota. Hook tarjoaa mutaation vastauksesta tilat isPending, isError, isSuccess, error ja data.
import { useMutation } from '@tanstack/react-query';
async function createPost(newPost) {
const response = await fetch('https://api.example.com/posts', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(newPost),
});
if (!response.ok) throw new Error('Failed to create post');
return response.json();
}
const { mutate, isPending, isError } = useMutation({
mutationFn: createPost,
});mutaten ja mutateAsyncin kutsuminen
Käynnistäkää mutaatio kutsumalla mutate(variables)-funktiota. variables-argumentti välitetään suoraan mutationFn-funktiolle. mutate käynnistää toiminnon odottamatta tulosta eikä palauta Promisea. Käyttäkää hookin onSuccess- ja onError-callback-funktioita tulokseen reagoimiseen.
Käyttäkää sen sijaan mutateAsync(variables)-funktiota, kun tulosta on odotettava async-funktiossa, esimerkiksi onnistuneen julkaisun jälkeen siirtymistä varten. Ympäröikää mutateAsync aina try/catch-rakenteella, sillä käsittelemättömät hylkäykset aiheuttavat virheitä.
const { mutate, mutateAsync, isPending } = useMutation({
mutationFn: createPost,
});
// Using mutate (fire-and-forget):
function handleSubmit() {
mutate({ title: 'My Post', body: postContent });
}
// Using mutateAsync (awaitable):
async function handleSubmitAndNavigate() {
try {
const newPost = await mutateAsync({ title: 'My Post', body: postContent });
navigation.navigate('PostDetail', { id: newPost.id });
} catch (err) {
Alert.alert('Error', err.message);
}
}onSuccess: mutaation jälkeinen callback
onSuccess-callback suoritetaan, kun mutaatio valmistuu onnistuneesti. Se saa parametrikseen mutaation tulosdatan ja mutate-funktiolle välitetyt muuttujat. Käyttäkää onSuccess-callbackia asiaankuuluvien kyselyiden mitätöintiin, onnistumisesta ilmoittamiseen, lomakkeiden tyhjentämiseen tai näkymästä poistumiseen.
Voitte määrittää onSuccess-callbackin hookin tasolla (logiikalle, jota sovelletaan aina) ja välittää sen myös mutate(variables, { onSuccess }) -kutsun toisena argumenttina kutsukohtaista mukauttamista varten.
import { useMutation, useQueryClient } from '@tanstack/react-query';
const queryClient = useQueryClient();
const { mutate } = useMutation({
mutationFn: createPost,
onSuccess: (newPost, variables) => {
// Refresh the posts list:
queryClient.invalidateQueries({ queryKey: ['posts'] });
// Show success:
Alert.alert('Post created!', newPost.title);
// Reset form:
resetForm();
},
onError: (error) => {
Alert.alert('Error', error.message);
},
});Välimuistin mitätöinti mutaation jälkeen
Välimuistin mitätöinti tarkoittaa välimuistissa olevien kyselyiden merkitsemistä vanhentuneiksi mutaation jälkeen, jotta ne hakevat tuoreen datan. Käyttäkää queryClient.invalidateQueries -funktiota yhdessä kyselyavaimen kanssa. Osittainen avainten täsmäytys on tuettu — avaimen ['posts'] mitätöinti mitätöi kaikki kyselyt, joiden avain alkaa merkkijonolla ['posts'], mukaan lukien ['posts', userId].
Mitätöinti käynnistää taustalla uuden haun kaikille aktiivisille (liitetyille) kyselyille, joiden avaimet täsmäävät. Näitä kyselyitä käyttävät komponentit näyttävät tuoreen datan yhden verkkopyyntöön kuluvan edestakaisen kierroksen kuluessa.
const { mutate: deletePost } = useMutation({
mutationFn: (postId) =>
fetch('/api/posts/' + postId, { method: 'DELETE' }),
onSuccess: (data, postId) => {
// Invalidate the posts list:
queryClient.invalidateQueries({ queryKey: ['posts'] });
// Also invalidate the specific post's cache:
queryClient.invalidateQueries({ queryKey: ['post', postId] });
},
});Optimistiset päivitykset
Optimistiset päivitykset päivittävät käyttöliittymän heti ennen kuin palvelin vahvistaa mutaation. Jos mutaatio onnistuu, oletettu muutos vahvistetaan. Jos se epäonnistuu, käyttöliittymä palautetaan edelliseen tilaan. Näin toiminnot tuntuvat tapahtuvan välittömästi — palvelimen vastausta ei tarvitse odottaa.
Toteuttakaa optimistiset päivitykset onMutate-callbackissa: tallentakaa välimuistin nykyinen tilanne, päivittäkää välimuisti heti ja palauttakaa aiempi tila tarvittaessa onError-callbackissa. React Query tarjoaa queryClient.setQueryData -funktion välimuistin manuaaliseen päivittämiseen.
const { mutate: likePost } = useMutation({
mutationFn: (postId) => fetch('/api/posts/' + postId + '/like', { method: 'POST' }),
onMutate: async (postId) => {
await queryClient.cancelQueries({ queryKey: ['posts'] });
const snapshot = queryClient.getQueryData(['posts']);
// Optimistically add like:
queryClient.setQueryData(['posts'], (old) =>
old.map(p => p.id === postId ? { ...p, likes: p.likes + 1 } : p)
);
return { snapshot }; // return for rollback
},
onError: (err, postId, context) => {
queryClient.setQueryData(['posts'], context.snapshot); // rollback
},
});Mutaation tila ja käyttöliittymän palautteet
Käyttäkää mutaation tilakenttiä asianmukaisen käyttöliittymäpalautteen tarjoamiseen. isPending on true, kun mutaatio on käynnissä — poistakaa lähetyspainike käytöstä ja näyttäkää latausilmaisin. isSuccess on true onnistuneen valmistumisen jälkeen — näyttäkää onnistumisviesti. isError on true, jos mutaatio epäonnistui — näyttäkää virheviesti.
React Query nollaa mutaation tilan automaattisesti määritettävän gcTime-ajan kuluttua. Voitte nollata tilan manuaalisesti esimerkiksi salliaksenne uuden yrityksen kutsumalla hookin palauttamaa reset()-funktiota.
const { mutate, isPending, isError, isSuccess, error, reset } = useMutation({
mutationFn: submitForm,
});
return (
<View>
<TextInput value={text} onChangeText={setText} editable={!isPending} />
<Button
title={isPending ? 'Submitting...' : 'Submit'}
onPress={() => mutate({ text })}
disabled={isPending}
/>
{isError && <Text style={{ color: 'red' }}>{error.message}</Text>}
{isSuccess && <Text style={{ color: 'green' }}>Saved!</Text>}
</View>
);Välimuistin suora päivittäminen mutaation jälkeen
Sen sijaan, että mitätöisitte välimuistin ja hakisitte datan uudelleen, voitte päivittää välimuistin suoraan mutaation vastauksella käyttämällä queryClient.setQueryData -funktiota. Tämä on tehokkaampaa, kun palvelin palauttaa päivitetyn datan mutaation vastauksessa — voitte lisätä sen luetteloon ilman ylimääräistä verkkopyyntöä.
Tämä toimintamalli — välimuistin päivittäminen palvelimen vastauksella mitätöinnin sijaan — säästää yhden verkkopyyntöön kuluvan edestakaisen kierroksen ja sopii luetteloihin, joissa uusi kohde halutaan liittää heti.
const { mutate } = useMutation({
mutationFn: createPost,
onSuccess: (newPost) => {
// Append new post to cached list directly:
queryClient.setQueryData(['posts'], (oldPosts) => {
if (!oldPosts) return [newPost];
return [newPost, ...oldPosts]; // prepend new post
});
// No invalidation needed — cache is already up to date!
},
});Globaalit mutaatiocallbackit QueryClientin kautta
Voitte määrittää globaalit mutaatiocallbackit QueryClientin defaultOptions.mutations-asetuksissa lokitusta, virheraportointia tai tunnisteen päivittämistä varten, kun näitä toimintoja tarvitaan kaikissa sovelluksen mutaatioissa. Paikalliset mutaatioasetukset ohittavat globaalit asetukset, mutta molempia voidaan käyttää samanaikaisesti.
Yleinen käyttötapaus on globaali onError-callback, joka tarkistaa 401 Unauthorized -vastaukset ja käynnistää uloskirjautumisen tai tunnisteen päivityksen jokaiselle mutaatiolle ilman, että samaa logiikkaa tarvitsee toistaa jokaisessa yksittäisessä useMutation-kutsussa.
const queryClient = new QueryClient({
defaultOptions: {
mutations: {
onError: (error) => {
// Global error handling for all mutations:
if (error.status === 401) {
handleUnauthorized();
} else {
console.error('Mutation error:', error.message);
}
},
},
},
});Mutaatiot tiedostojen lähetyksessä
Mutaatiot käsittelevät tiedostojen lähetyksen hyväksymällä FormDatan muuttujiksi. mutationFn luo FormData-olion ja lähettää sen fetchillä käyttäen multipart/form-data-sisältötyyppiä. React Query hallitsee lataus- ja virhetilaa samalla tavalla kuin minkä tahansa muun mutaation yhteydessä.
Suurten tiedostojen lähetyksessä voitte seurata etenemistä käyttämällä XHR:ää hyödyntävää mukautettua fetch-käärettä ja tallentamalla etenemisen erilliseen tilamuuttujaan, jota päivitetään onUploadProgress-toimintamallin avulla.
const { mutate: uploadPhoto, isPending } = useMutation({
mutationFn: async ({ uri, userId }) => {
const formData = new FormData();
formData.append('photo', {
uri,
type: 'image/jpeg',
name: 'photo.jpg',
});
formData.append('userId', userId);
const response = await fetch('/api/photos', {
method: 'POST',
body: formData,
// Do NOT set Content-Type — let fetch set multipart boundary
});
return response.json();
},
onSuccess: () => queryClient.invalidateQueries({ queryKey: ['photos'] }),
});Mutaatioketjut
Kun työnkulku edellyttää useita peräkkäisiä palvelinoperaatioita, esimerkiksi tilauksen luomista ja sen jälkeen maksun käsittelyä, ketjuttakaa mutaatiot peräkkäin mutateAsync-funktion avulla. Kukin mutaatio voi käyttää edellisen mutaation tulosta syötteenään. Ympäröikää ketju try/catch-rakenteella virheiden käsittelyä varten.
Jos jokin välivaihe epäonnistuu, aiemmat vaiheet on ehkä peruutettava manuaalisesti tai käynnistettävä korvaavia tapahtumia. Suunnitelkaa rajapintanne mahdollisuuksien mukaan atomisiksi, jotta virheistä palautuminen asiakkaan puolella olisi yksinkertaisempaa.
const { mutateAsync: createOrder } = useMutation({ mutationFn: apiCreateOrder });
const { mutateAsync: processPayment } = useMutation({ mutationFn: apiProcessPayment });
async function handleCheckout(cartData, paymentInfo) {
try {
const order = await createOrder(cartData);
const payment = await processPayment({ orderId: order.id, ...paymentInfo });
queryClient.invalidateQueries({ queryKey: ['orders'] });
navigation.navigate('OrderConfirmation', { orderId: order.id });
} catch (error) {
Alert.alert('Checkout failed', error.message);
}
}Pikatarkistus
Testatkaa, miten hyvin ymmärrätte tämän oppitunnin React Native Mobile Development -käsitteet.
Oppitunnin kertaus
Tässä oppitunnissa opitte, että useMutation käsittelee kirjoitusoperaatioita (POST/PUT/DELETE) ja tarjoaa isPending-, isError- ja isSuccess-tilat, onSuccess on ensisijainen paikka kutsua queryClient.invalidateQueries-funktiota asiaankuuluvien välimuistissa olevien tietojen päivittämiseksi sekä että onMutate-funktion avulla toteutetut optimistiset päivitykset päivittävät välimuistin heti ja sisältävät palautustilannevedoksen palvelinpyynnön epäonnistumista varten. Seuraavaksi tallennamme React Query -välimuistin AsyncStorageen offline-first-toimintaa varten.
Opi JavaScript tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 30
- Oppitunnit
- 120
Usein kysytyt kysymykset
Onko oppitunti ”Mutaatiot useMutationilla ja välimuistin mitätöinti” ilmainen?
Kyllä — voit lukea täällä verkossa kokonaan ilmaiseksi mitkä tahansa React Native Academy-oppimispolun 3 oppituntia, myös oppitunnin “Mutaatiot useMutationilla ja välimuistin mitätöinti”. Sen jälkeen CoddyKit PRO avaa kaikki oppitunnit sekä interaktiiviset harjoitukset sisäänrakennetulla koodieditorilla ja ympäri vuorokauden toimivalla tekoälytuutorilla. React Native Academy-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”Mutaatiot useMutationilla ja välimuistin mitätöinti”?
Käyttäkää useMutationia tietojen POST-lähetykseen, mitätöikää liittyvät kyselyt onnistumisen jälkeen, jotta luettelo päivittyy automaattisesti, ja näyttäkää optimistinen käyttöliittymäpalaute pyynnön… Harjoittelet React Native Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni React Native Academy-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin React Native Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.
Kuinka kauan ”Mutaatiot useMutationilla ja välimuistin mitätöinti”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä React Native Academy-oppitunnilla?
Kyllä. Jokainen React Native Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- QueryClient, QueryClientProvider ja useQuery
- Mutaatiot useMutationilla ja välimuistin mitätöinti
- Kyselyvälimuistin säilyttäminen AsyncStoragella
- Taustalla tehtävä uudelleenlataus ja stale time -määritykset