Avastage Reacti useActionState'i koos olekumasinatega, et luua robustseid ja ennustatavaid kasutajaliideseid. Õppige tegevuste olekuüleminekute loogikat.
Reacti useActionState olekumasin: tegevuste olekuĂĽleminekute loogika valdamine
Reacti useActionState
on võimas hook, mis on kasutusele võetud React 19-s (praegu canary-versioonis) ja on mõeldud asünkroonsete olekuvärskenduste lihtsustamiseks, eriti serveri tegevustega tegelemisel. Kombineerituna olekumasinaga pakub see elegantse ja robustse viisi keerukate kasutajaliidese interaktsioonide ja olekuüleminekute haldamiseks. See blogipostitus süveneb sellesse, kuidas tõhusalt kasutada useActionState
'i koos olekumasinaga, et luua ennustatavaid ja hooldatavaid Reacti rakendusi.
Mis on olekumasin?
Olekumasin on matemaatiline arvutusmudel, mis kirjeldab süsteemi käitumist piiratud arvu olekute ja nende olekute vaheliste üleminekutena. Iga olek esindab süsteemi eristatavat seisundit ja üleminekud esindavad sündmusi, mis põhjustavad süsteemi liikumise ühest olekust teise. Mõelge sellest kui vooskeemist, kuid rangemate reeglitega selle kohta, kuidas sammude vahel liikuda saab.
Olekumasina kasutamine Reacti rakenduses pakub mitmeid eeliseid:
- Ennustatavus: Olekumasinad jõustavad selge ja ennustatava kontrollivoo, muutes rakenduse käitumise mõistmise lihtsamaks.
- Hooldatavus: Eraldades olekuloogika kasutajaliidese renderdamisest, parandavad olekumasinad koodi organiseeritust ja muudavad rakenduse hooldamise ja uuendamise lihtsamaks.
- Testitavus: Olekumasinad on oma olemuselt testitavad, sest saate hõlpsasti määratleda iga oleku ja ülemineku oodatava käitumise.
- Visuaalne esitus: Olekumasinaid saab visuaalselt esitada, mis aitab rakenduse käitumist teistele arendajatele või sidusrühmadele edastada.
Tutvustame useActionState
'i
useActionState
hook võimaldab teil käsitleda tegevuse tulemust, mis võib potentsiaalselt muuta rakenduse olekut. See on loodud sujuvaks töötamiseks serveri tegevustega, kuid seda saab kohandada ka kliendipoolsete tegevuste jaoks. See pakub puhta viisi laadimise olekute, vigade ja tegevuse lõpptulemuse haldamiseks, muutes reageerivate ja kasutajasõbralike kasutajaliideste loomise lihtsamaks.
Siin on põhiline näide, kuidas useActionState
'i kasutatakse:
const [state, dispatch] = useActionState(async (prevState, formData) => {
// Teie tegevuse loogika siin
try {
const result = await someAsyncFunction(formData);
return { ...prevState, data: result };
} catch (error) {
return { ...prevState, error: error.message };
}
}, { data: null, error: null });
Selles näites:
- Esimene argument on asĂĽnkroonne funktsioon, mis teostab tegevuse. See saab eelmise oleku ja vormi andmed (kui on kohaldatav).
- Teine argument on algolek.
- Hook tagastab massiivi, mis sisaldab praegust olekut ja dispatch-funktsiooni.
useActionState
'i ja olekumasinate kombineerimine
Tõeline jõud peitub useActionState
'i ja olekumasina kombineerimises. See võimaldab teil määratleda keerukaid olekuüleminekuid, mille käivitavad asünkroonsed tegevused. Vaatleme stsenaariumit: lihtne e-kaubanduse komponent, mis hangib toote detaile.
Näide: Toote detailide hankimine
Määratleme oma toote detailide komponendi jaoks järgmised olekud:
- Idle (Ootel): Algolek. Toote detaile pole veel hangitud.
- Loading (Laadimine): Olek, mille ajal toote detaile hangitakse.
- Success (Edukas): Olek pärast toote detailide edukat hankimist.
- Error (Viga): Olek, kui toote detailide hankimisel ilmnes viga.
Seda olekumasinat saame esitada objektina:
const productDetailsMachine = {
initial: 'idle',
states: {
idle: {
on: {
FETCH: 'loading',
},
},
loading: {
on: {
SUCCESS: 'success',
ERROR: 'error',
},
},
success: {
type: 'final',
},
error: {
on: {
FETCH: 'loading',
},
},
},
};
See on lihtsustatud esitus; teegid nagu XState pakuvad keerukamaid olekumasina implementatsioone funktsioonidega nagu hierarhilised olekud, paralleelsed olekud ja kaitsed (guards).
Reacti implementatsioon
NĂĽĂĽd integreerime selle olekumasina useActionState
'iga Reacti komponendis.
import React from 'react';
// Paigaldage XState, kui soovite täielikku olekumasina kogemust. Selle lihtsa näite jaoks kasutame tavalist objekti.
// import { createMachine, useMachine } from 'xstate';
const productDetailsMachine = {
initial: 'idle',
states: {
idle: {
on: {
FETCH: 'loading',
},
},
loading: {
on: {
SUCCESS: 'success',
ERROR: 'error',
},
},
success: {
type: 'final',
},
error: {
on: {
FETCH: 'loading',
},
},
},
};
function ProductDetails({ productId }) {
const [state, dispatch] = React.useReducer(
(state, event) => {
const nextState = productDetailsMachine.states[state].on[event];
return nextState || state; // Tagastage järgmine olek või praegune, kui üleminekut pole määratletud
},
productDetailsMachine.initial
);
const [productData, setProductData] = React.useState(null);
const [error, setError] = React.useState(null);
React.useEffect(() => {
if (state === 'loading') {
const fetchData = async () => {
try {
const response = await fetch(`https://api.example.com/products/${productId}`); // Asendage oma API otspunktiga
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
setProductData(data);
setError(null);
dispatch('SUCCESS');
} catch (e) {
setError(e.message);
setProductData(null);
dispatch('ERROR');
}
};
fetchData();
}
}, [state, productId, dispatch]);
const handleFetch = () => {
dispatch('FETCH');
};
return (
Toote detailid
{state === 'idle' && }
{state === 'loading' && Laadimine...
}
{state === 'success' && (
{productData.name}
{productData.description}
Hind: ${productData.price}
)}
{state === 'error' && Viga: {error}
}
);
}
export default ProductDetails;
Selgitus:
- Me defineerime
productDetailsMachine
'i kui lihtsa JavaScripti objekti, mis esindab meie olekumasinat. - Me kasutame
React.useReducer
'it olekuĂĽleminekute haldamiseks vastavalt meie masinale. - Me kasutame Reacti
useEffect
hook'i andmete hankimise käivitamiseks, kui olek on 'loading'. handleFetch
funktsioon saadab 'FETCH' sĂĽndmuse, algatades laadimise oleku.- Komponent renderdab erinevat sisu vastavalt praegusele olekule.
useActionState
'i kasutamine (hĂĽpoteetiline - React 19 funktsioon)
Kuigi useActionState
pole veel täielikult saadaval, näeks implementatsioon välja selline, kui see kättesaadavaks muutub, pakkudes puhtamat lähenemist:
import React from 'react';
//import { useActionState } from 'react'; // Eemaldage kommentaar, kui see on saadaval
const productDetailsMachine = {
initial: 'idle',
states: {
idle: {
on: {
FETCH: 'loading',
},
},
loading: {
on: {
SUCCESS: 'success',
ERROR: 'error',
},
},
success: {
type: 'final',
},
error: {
on: {
FETCH: 'loading',
},
},
},
};
function ProductDetails({ productId }) {
const initialState = { state: productDetailsMachine.initial, data: null, error: null };
// HĂĽpoteetiline useActionState'i implementatsioon
const [newState, dispatch] = React.useReducer(
(state, event) => {
const nextState = productDetailsMachine.states[state.state].on[event];
return nextState ? { ...state, state: nextState } : state; // Tagastage järgmine olek või praegune, kui üleminekut pole määratletud
},
initialState
);
const handleFetchProduct = async () => {
dispatch('FETCH');
try {
const response = await fetch(`https://api.example.com/products/${productId}`); // Asendage oma API otspunktiga
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();
// Edukalt alla laaditud - saatke SUCCESS koos andmetega!
dispatch('SUCCESS');
// Salvestage laaditud andmed lokaalsesse olekusse. Reducer'i sees ei saa dispatch'i kasutada.
newState.data = data; // Uuendage väljaspool dispetšerit
} catch (error) {
// Ilmnes viga - saatke ERROR koos veateatega!
dispatch('ERROR');
// Salvestage viga uude muutujasse, mida render() funktsioonis kuvada
newState.error = error.message;
}
//}, initialState);
};
return (
Toote detailid
{newState.state === 'idle' && }
{newState.state === 'loading' && Laadimine...
}
{newState.state === 'success' && newState.data && (
{newState.data.name}
{newState.data.description}
Hind: ${newState.data.price}
)}
{newState.state === 'error' && newState.error && Viga: {newState.error}
}
);
}
export default ProductDetails;
Oluline märkus: See näide on hüpoteetiline, kuna useActionState
pole veel täielikult saadaval ja selle täpne API võib muutuda. Olen selle asendanud standardse useReducer'iga, et põhilogiika töötaks. Siiski on eesmärk näidata, kuidas te seda *kasutaksite*, kui see muutub kättesaadavaks ja peate useReducer'i asendama useActionState'iga. Tulevikus peaks see kood useActionState
'iga töötama minimaalsete muudatustega nagu selgitatud, lihtsustades oluliselt asünkroonset andmekäsitlust.
useActionState
'i ja olekumasinate kasutamise eelised
- Murede selge eraldamine: Olekuloogika on kapseldatud olekumasinasse, samas kui kasutajaliidese renderdamise eest hoolitseb Reacti komponent.
- Parem koodi loetavus: Olekumasin pakub rakenduse käitumisest visuaalset esitust, muutes selle mõistmise ja hooldamise lihtsamaks.
- Lihtsustatud asünkroonne käsitlemine:
useActionState
sujuvdab asünkroonsete tegevuste käsitlemist, vähendades korduvat koodi. - Täiustatud testitavus: Olekumasinad on oma olemuselt testitavad, võimaldades teil hõlpsasti kontrollida oma rakenduse käitumise õigsust.
Täpsemad kontseptsioonid ja kaalutlused
XState'i integreerimine
Keerukamate olekuhalduse vajaduste jaoks kaaluge spetsiaalse olekumasina teegi, näiteks XState, kasutamist. XState pakub võimsat ja paindlikku raamistikku olekumasinate määratlemiseks ja haldamiseks, funktsioonidega nagu hierarhilised olekud, paralleelsed olekud, kaitsed ja tegevused.
// Näide XState'i kasutamisest
import { createMachine, useMachine } from 'xstate';
const productDetailsMachine = createMachine({
id: 'productDetails',
initial: 'idle',
states: {
idle: {
on: {
FETCH: 'loading',
},
},
loading: {
invoke: {
id: 'fetchProduct',
src: (context, event) => fetch(`https://api.example.com/products/${context.productId}`).then(res => res.json()),
onDone: {
target: 'success',
actions: assign({ product: (context, event) => event.data })
},
onError: {
target: 'error',
actions: assign({ error: (context, event) => event.data })
}
}
},
success: {
type: 'final',
},
error: {
on: {
FETCH: 'loading',
},
},
},
}, {
services: {
fetchProduct: (context, event) => fetch(`https://api.example.com/products/${context.productId}`).then(res => res.json())
}
});
See pakub deklaratiivsemat ja robustsemat viisi oleku haldamiseks. Kindlasti installige see käsuga: npm install xstate
Globaalne olekuhaldus
Rakenduste puhul, millel on keerukad olekuhalduse nõuded mitme komponendi vahel, kaaluge globaalse olekuhalduse lahenduse, nagu Redux või Zustand, kasutamist koos olekumasinatega. See võimaldab teil tsentraliseerida oma rakenduse oleku ja seda hõlpsasti komponentide vahel jagada.
Olekumasinate testimine
Olekumasinate testimine on ülioluline, et tagada teie rakenduse korrektsus ja usaldusväärsus. Saate kasutada testimisraamistikke nagu Jest või Mocha, et kirjutada oma olekumasinatele ühikteste, kontrollides, et need liiguvad ootuspäraselt olekute vahel ja käsitlevad erinevaid sündmusi korrektselt.
Siin on lihtne näide:
// Näide Jest testist
import { interpret } from 'xstate';
import { productDetailsMachine } from './productDetailsMachine';
describe('productDetailsMachine', () => {
it('should transition from idle to loading on FETCH event', (done) => {
const service = interpret(productDetailsMachine).onTransition((state) => {
if (state.value === 'loading') {
expect(state.value).toBe('loading');
done();
}
});
service.start();
service.send('FETCH');
});
});
Rahvusvahelistamine (i18n)
Globaalsele publikule rakenduste loomisel on rahvusvahelistamine (i18n) hädavajalik. Veenduge, et teie olekumasina loogika ja kasutajaliidese renderdamine on korralikult rahvusvahelistatud, et toetada mitut keelt ja kultuurilist konteksti. Kaaluge järgmist:
- Tekstisisu: Kasutage i18n-teeke tekstisisu tõlkimiseks vastavalt kasutaja lokaadile.
- Kuupäeva ja kellaaja vormingud: Kasutage lokaaditeadlikke kuupäeva ja kellaaja vormindamise teeke, et kuvada kuupäevi ja kellaaegu kasutaja piirkonnale sobivas vormingus.
- Valuuta vormingud: Kasutage lokaaditeadlikke valuuta vormindamise teeke, et kuvada valuutaväärtusi kasutaja piirkonnale sobivas vormingus.
- Arvuvormingud: Kasutage lokaaditeadlikke arvuvormindamise teeke, et kuvada numbreid kasutaja piirkonnale sobivas vormingus (nt komakohad, tuhandete eraldajad).
- Paremalt vasakule (RTL) paigutus: Toetage RTL-paigutusi keelte nagu araabia ja heebrea jaoks.
Neid i18n aspekte arvesse võttes saate tagada, et teie rakendus on globaalsele publikule kättesaadav ja kasutajasõbralik.
Kokkuvõte
Reacti useActionState
'i kombineerimine olekumasinatega pakub võimsa lähenemise robustsete ja ennustatavate kasutajaliideste loomiseks. Eraldades olekuloogika kasutajaliidese renderdamisest ja jõustades selge kontrollivoo, parandavad olekumasinad koodi organiseeritust, hooldatavust ja testitavust. Kuigi useActionState
on alles tulevane funktsioon, valmistab olekumasinate integreerimise mõistmine teid ette selle eeliste kasutamiseks, kui see kättesaadavaks muutub. Teegid nagu XState pakuvad veelgi arenenumaid olekuhalduse võimalusi, muutes keeruka rakendusloogika käsitlemise lihtsamaks.
Omaks võttes olekumasinaid ja useActionState
'i, saate tõsta oma Reacti arendusoskusi ja luua rakendusi, mis on usaldusväärsemad, hooldatavamad ja kasutajasõbralikumad kasutajatele üle kogu maailma.