Atraskite React serverio veiksmų atsako srautinį perdavimą progresyviems formų atsakams. Išmokite kurti greitesnes, jautresnes formas geresnei naudotojo patirčiai.
React serverio veiksmų atsako srautinis perdavimas: progresyvus formos atsakas geresnei naudotojo patirčiai
React serverio veiksmai (angl. Server Actions) pristato galingą paradigmos pokytį, kaip mes tvarkome serverio pusės operacijas savo React programose. Viena iš įdomiausių funkcijų yra galimybė perduoti atsakymus srautiniu būdu palaipsniui, leidžiant mums pateikti nedelsiantį grįžtamąjį ryšį vartotojams dar prieš baigiant visą operaciją. Tai ypač naudinga formoms, kur galime sukurti jautresnę ir labiau įtraukiančią vartotojo patirtį, atnaujindami vartotojo sąsają, kai tik duomenys tampa prieinami.
Kas yra React serverio veiksmai
Serverio veiksmai – tai asinchroninės funkcijos, kurios vykdomos serveryje, inicijuotos iš React komponentų. Jos siūlo keletą pranašumų, palyginti su tradiciniais API iškvietimais:
- Pagerintas saugumas: Serverio veiksmai vykdomi tiesiogiai serveryje, sumažinant riziką atskleisti jautrius duomenis ar logiką klientui.
- Mažiau pasikartojančio kodo: Jie pašalina poreikį kurti atskirus API maršrutus ir duomenų gavimo logiką kliento pusėje.
- Padidintas našumas: Jie gali pasinaudoti serverio pusės generavimu (SSR) ir podėliavimu (angl. caching) greitesniam pradiniam užkrovimo laikui ir geresniam našumui.
- Tipų saugumas: Naudojant TypeScript, serverio veiksmai užtikrina visapusišką tipų saugumą, garantuodami duomenų nuoseklumą tarp kliento ir serverio.
Atsako srautinio perdavimo galia
Tradicinis formų pateikimas dažnai apima visų duomenų siuntimą į serverį, atsakymo laukimą ir tada atitinkamą vartotojo sąsajos atnaujinimą. Tai gali sukelti suvokiamą vėlavimą, ypač sudėtingoms formoms ar esant lėtam tinklo ryšiui. Atsako srautinis perdavimas (angl. Response streaming) leidžia serveriui siųsti duomenis klientui dalimis, suteikiant galimybę palaipsniui atnaujinti vartotojo sąsają, kai tik duomenys tampa prieinami.
Įsivaizduokite formą, kuri apskaičiuoja sudėtingą kainą pagal vartotojo įvestį. Užuot laukus, kol bus baigtas visas skaičiavimas, serveris gali srautiniu būdu siųsti tarpinius rezultatus klientui, teikdamas vartotojui grįžtamąjį ryšį realiu laiku. Tai gali žymiai pagerinti vartotojo patirtį ir padaryti programą jautresnę.
Progresyvaus formos atsako įgyvendinimas su serverio veiksmais
Panagrinėkime pavyzdį, kaip įgyvendinti progresyvų formos atsaką su React serverio veiksmais.
Pavyzdys: realaus laiko valiutos keitiklis
Sukursime paprastą valiutos keitiklio formą, kuri teikia realaus laiko valiutų kursų atnaujinimus, kai vartotojas įveda sumą.
1. Serverio veiksmo paruošimas
Pirmiausia apibrėžiame serverio veiksmą, kuris tvarko valiutos konvertavimą.
// server/actions.ts
'use server';
import { unstable_cache } from 'next/cache';
async function getExchangeRate(fromCurrency: string, toCurrency: string): Promise<number> {
// Imituojamas valiutos kurso gavimas iš išorinės API
console.log(`Fetching exchange rate for ${fromCurrency} to ${toCurrency}`);
await new Promise(resolve => setTimeout(resolve, 500)); // Imituojamas tinklo vėlavimas
if (fromCurrency === 'USD' && toCurrency === 'EUR') return 0.92;
if (fromCurrency === 'EUR' && toCurrency === 'USD') return 1.09;
if (fromCurrency === 'USD' && toCurrency === 'JPY') return 145;
if (fromCurrency === 'JPY' && toCurrency === 'USD') return 0.0069;
throw new Error(`Exchange rate not found for ${fromCurrency} to ${toCurrency}`);
}
export const convertCurrency = async (prevState: any, formData: FormData) => {
const fromCurrency = formData.get('fromCurrency') as string;
const toCurrency = formData.get('toCurrency') as string;
const amount = Number(formData.get('amount'));
try {
if (!fromCurrency || !toCurrency || isNaN(amount)) {
return { message: 'Please provide valid input.' };
}
// Imituojamas atsako srautinis perdavimas
await new Promise(resolve => setTimeout(resolve, 250));
const exchangeRate = await unstable_cache(
async () => getExchangeRate(fromCurrency, toCurrency),
[`exchange-rate-${fromCurrency}-${toCurrency}`],
{ tags: [`exchange-rate-${fromCurrency}-${toCurrency}`] }
)();
await new Promise(resolve => setTimeout(resolve, 250));
const convertedAmount = amount * exchangeRate;
return { message: `Konvertuota suma: ${convertedAmount.toFixed(2)} ${toCurrency}` };
} catch (e: any) {
console.error(e);
return { message: 'Nepavyko konvertuoti valiutos.' };
}
};
Šiame pavyzdyje `convertCurrency` serverio veiksmas gauna valiutos kursą (imituojama su vėlavimu) ir apskaičiuoja konvertuotą sumą. Pridėjome dirbtinius vėlavimus naudodami `setTimeout`, kad imituotume tinklo delsą ir pademonstruotume srautinio perdavimo efektą.
2. React komponento įgyvendinimas
Toliau sukuriame React komponentą, kuris naudoja serverio veiksmą.
// app/page.tsx
'use client';
import { useState, useTransition } from 'react';
import { convertCurrency } from './server/actions';
import { useFormState } from 'react-dom';
export default function CurrencyConverter() {
const [fromCurrency, setFromCurrency] = useState('USD');
const [toCurrency, setToCurrency] = useState('EUR');
const [amount, setAmount] = useState('');
const [isPending, startTransition] = useTransition();
const [state, formAction] = useFormState(convertCurrency, { message: '' });
const handleSubmit = async (event: React.FormEvent) => {
event.preventDefault();
startTransition(() => {
formAction(new FormData(event.target as HTMLFormElement));
});
};
return (
<div>
<h2>Realaus laiko valiutos keitiklis</h2>
<form action={handleSubmit}>
<label htmlFor="fromCurrency">Iš:</label>
<select id="fromCurrency" name="fromCurrency" value={fromCurrency} onChange={(e) => setFromCurrency(e.target.value)}>
<option value="USD">USD</option>
<option value="EUR">EUR</option>
<option value="JPY">JPY</option>
</select>
<label htmlFor="toCurrency">Į:</label>
<select id="toCurrency" name="toCurrency" value={toCurrency} onChange={(e) => setToCurrency(e.target.value)}>
<option value="EUR">EUR</option>
<option value="USD">USD</option>
<option value="JPY">JPY</option>
</select>
<label htmlFor="amount">Suma:</label>
<input
type="number"
id="amount"
name="amount"
value={amount}
onChange={(e) => setAmount(e.target.value)}
/>
<button type="submit" disabled={isPending}>
{isPending ? 'Konvertuojama...' : 'Konvertuoti'}
</button>
</form>
<p>{state.message}</p>
</div>
);
}
Svarbiausi momentai:
- Naudojame `useFormState` „kabliuką“ (hook), kad valdytume formos būseną ir iškviestume serverio veiksmą.
- `isPending` būsena iš `useTransition` išjungia pateikimo mygtuką ir rodo pranešimą „Konvertuojama...“, kol veiksmas vykdomas, suteikdamas vartotojui grįžtamąjį ryšį.
- `formAction` funkcija, kurią grąžina `useFormState`, automatiškai tvarko formos pateikimą ir atnaujina būseną su atsakymu iš serverio veiksmo.
3. Progresyvių atnaujinimų supratimas
Kai vartotojas pateikia formą, iškviečiama `handleSubmit` funkcija. Ji sukuria `FormData` objektą iš formos ir perduoda jį `formAction` funkcijai. Tada serverio veiksmas vykdomas serveryje. Dėl dirbtinių vėlavimų, įdiegtų serverio veiksme, pastebėsite šiuos dalykus:
- Pateikimo mygtukas beveik iš karto pasikeičia į „Konvertuojama...“.
- Po trumpo vėlavimo (250 ms) kodas imituoja valiutos kurso gavimą.
- Apskaičiuojama konvertuota suma, o rezultatas siunčiamas atgal klientui.
- Atnaujinamas `state.message` React komponente, parodant konvertuotą sumą.
Tai parodo, kaip atsako srautinis perdavimas leidžia mums teikti tarpinius atnaujinimus vartotojui, kai tik duomenys tampa prieinami, o tai lemia jautresnę ir labiau įtraukiančią vartotojo patirtį.
Progresyvaus formos atsako privalumai
- Pagerinta vartotojo patirtis: Suteikia nedelsiantį grįžtamąjį ryšį vartotojams, todėl programa atrodo jautresnė ir mažiau stringanti.
- Sumažinta suvokiama delsa: Rodydami tarpinius rezultatus, vartotojai procesą suvokia kaip greitesnį, net jei bendra operacija trunka tiek pat laiko.
- Padidintas įsitraukimas: Išlaiko vartotojų susidomėjimą teikdami realaus laiko atnaujinimus ir neleisdami jiems palikti formos dėl suvokiamų vėlavimų.
- Padidėję konversijų rodikliai: Sklandesnė ir jautresnė vartotojo patirtis gali lemti didesnius konversijų rodiklius, ypač sudėtingoms formoms.
Pažangios technikos
1. `useOptimistic` naudojimas momentiniams vartotojo sąsajos atnaujinimams
`useOptimistic` „kabliukas“ leidžia optimistiškai atnaujinti vartotojo sąsają dar prieš baigiantis serverio veiksmui. Tai gali suteikti dar greitesnį suvokiamą atsako laiką, nes vartotojo sąsaja nedelsiant atspindi laukiamą rezultatą.
import { useOptimistic } from 'react';
function MyComponent() {
const [optimisticState, addOptimistic] = useOptimistic(
initialState,
(state, newUpdate) => {
// Grąžinama nauja būsena, pagrįsta atnaujinimu
return { ...state, ...newUpdate };
}
);
const handleClick = async () => {
addOptimistic({ someValue: 'optimistic update' });
await myServerAction();
};
return (
<div>
<p>{optimisticState.someValue}</p>
<button onClick={handleClick}>Update</button>
</div>
);
}
Valiutos keitiklio pavyzdyje galėtumėte optimistiškai atnaujinti konvertuotą sumą, remdamiesi dabartiniu valiutos kursu, taip suteikdami vartotojui momentinę peržiūrą dar prieš baigiantis realiam skaičiavimui serveryje. Jei serveris grąžina klaidą, galite atšaukti optimistinį atnaujinimą.
2. Klaidų apdorojimo ir atsarginių mechanizmų įgyvendinimas
Itin svarbu įgyvendinti patikimą klaidų apdorojimą ir atsarginius mechanizmus, kad būtų galima valdyti atvejus, kai serverio veiksmas nepavyksta arba nutrūksta tinklo ryšys. Galite naudoti `try...catch` bloką serverio veiksme, kad pagautumėte klaidas ir grąžintumėte atitinkamą klaidos pranešimą klientui.
// server/actions.ts
export const convertCurrency = async (prevState: any, formData: FormData) => {
// ...
try {
// ...
} catch (error: any) {
console.error(error);
return { message: 'Konvertuojant valiutą įvyko klaida. Bandykite dar kartą vėliau.' };
}
};
Kliento pusėje galite parodyti klaidos pranešimą vartotojui ir pasiūlyti galimybes pakartoti operaciją arba susisiekti su pagalba.
3. Valiutų kursų podėliavimas našumui pagerinti
Valiutų kursų gavimas iš išorinės API gali tapti našumo kliūtimi. Norėdami pagerinti našumą, galite naudoti valiutų kursų podėliavimą (angl. caching) su mechanizmu, tokiu kaip Redis ar Memcached. `unstable_cache` iš Next.js (kaip parodyta pavyzdyje) suteikia integruotą podėliavimo sprendimą. Nepamirškite periodiškai anuliuoti podėlio, kad valiutų kursai būtų atnaujinti.
4. Tarptautinimo (Internationalization) aspektai
Kuriant programas pasaulinei auditorijai, svarbu atsižvelgti į tarptautinimą (i18n). Tai apima:
- Skaičių formatavimas: Naudokite atitinkamus skaičių formatus skirtingoms lokalėms (pvz., kablelius ar taškus kaip dešimtainius skyriklius).
- Valiutos formatavimas: Rodykite valiutų simbolius ir formatus pagal vartotojo lokalę.
- Datos ir laiko formatavimas: Naudokite atitinkamus datos ir laiko formatus skirtingoms lokalėms.
- Lokalizacija: Išverskite vartotojo sąsają į skirtingas kalbas.
Bibliotekos, tokios kaip `Intl` ir `react-intl`, gali padėti jums įgyvendinti i18n jūsų React programose.
Realaus pasaulio pavyzdžiai ir panaudojimo atvejai
- Elektroninė komercija: Realaus laiko siuntimo išlaidų ir pristatymo terminų rodymas, kai vartotojas prideda prekes į krepšelį.
- Finansinės programos: Realaus laiko akcijų kainų ir portfelio atnaujinimų teikimas.
- Kelionių užsakymas: Realaus laiko skrydžių kainų ir prieinamumo rodymas.
- Duomenų vizualizavimas: Duomenų atnaujinimų srautinis perdavimas diagramoms ir grafikams.
- Bendradarbiavimo įrankiai: Realaus laiko dokumentų ir projektų atnaujinimų rodymas.
Išvados
React serverio veiksmų atsako srautinis perdavimas siūlo galingą būdą pagerinti jūsų React programų vartotojo patirtį. Teikdami progresyvius formų atsakymus, galite kurti greitesnes, jautresnes ir labiau įtraukiančias formas, kurios išlaiko vartotojų susidomėjimą ir didina konversijų rodiklius. Derindami atsako srautinį perdavimą su tokiomis technikomis kaip optimistiniai atnaujinimai ir podėliavimas, galite sukurti išties išskirtinę vartotojo patirtį.
React serverio veiksmams toliau tobulėjant, galime tikėtis dar galingesnių funkcijų ir galimybių atsiradimo, dar labiau supaprastinančių sudėtingų ir dinamiškų interneto programų kūrimą.
Tolimesni tyrimai
Šis vadovas pateikia išsamią React serverio veiksmų atsako srautinio perdavimo ir jo taikymo progresyviems formų atsakams apžvalgą. Suprasdami čia aptartas sąvokas ir technikas, galite pasinaudoti šia galinga funkcija, kad sukurtumėte greitesnes, jautresnes ir labiau įtraukiančias interneto programas.