További reducer-ek a Redux-ban
Nyissuk meg termékalkalmazásunkat,
és benne a productsSlice.js fájlt. Valószínűleg
észrevetted, hogy a fetchProducts thunk-ot
külön függvényként hoztuk létre? Azért tettük
ezt, mert a createSlice nem támogatja a thunk-ok
megadását. Hogyan tudjuk ilyen esetben elérni,
hogy a products slice reducer-e reagáljon
azokra az action-ökre, amelyek a products
határain kívül lettek definiálva? Hiszen pontosan
azokat az action-öket kell feldolnunk,
amelyeket a fetchProducts thunk küld.
Ilyen esetekre a createSlice-nek van
egy extraReducers tulajdonsága, amely
lehetővé teszi további reducer-ek hozzáadását, amelyek
viszont azokat az action-öket fogják feldolgozni,
amelyek nem ebben a slice-ban lettek definiálva.
Most a createSlice függvény törzsében
a reducers tulajdonság után
adjunk hozzá még egy extraReducers metódust:
extraReducers() {},
Ennek a metódusnak egy builder objektumot
kell átadnunk, amelynek vannak metódusai, amelyek
segítségével további reducer-eket lehet
hozzáadni:
extraReducers(builder) {},
A builder egyik metódusát fogjuk használni -
a addCase metódust, amely első paraméterként egy
action creatort, második paraméterként pedig egy reducer-t fogad el. Az egyik
action, amelyet a fetchProducts fog küldeni
a lekérdezés során a
fetchProducts.pending, ami azt jelzi,
hogy a lekérdezés el lett küldve. Ebben az
esetben változtassuk meg a státuszt 'in progress'-re
(ezelőtt 'idle' volt):
extraReducers(builder) {
builder.addCase(fetchProducts.pending, (state) => {
state.status = 'in progress'
})
},
Most dolgozzuk fel a sikeres lekérdezés
esetén elküldött action-t. Itt nem csak a
státuszt fogjuk megváltoztatni a state-ben
'success'-re, hanem a termékeket is
átvesszük a products slice-ba
az action payload mezőjéből.
Ahhoz, hogy összegyűjtsük az összes terméket, szükségünk lesz
a concat metódusra:
extraReducers(builder) {
builder
.addCase(fetchProducts.pending, (state) => {
state.status = 'in progress'
})
.addCase(fetchProducts.fulfilled, (state, action) => {
state.status = 'success'
state.products = state.products.concat(action.payload)
})
},
Sikertelen lekérdezés esetén megváltoztatjuk
a státuszt 'fail'-re és a state-be
elmentjük a hibaüzenetet:
.addCase(fetchProducts.rejected, (state, action) => {
state.status = 'fail'
state.error = action.error.message
})
Ha most elindítjuk alkalmazásunkat
és a menüben rákattintunk a 'Products'-ra, akkor
pár másodperc múlva (emlékszel a késleltetésre,
amit a szerveren beállítottunk?) meglátjuk
a termékek listáját.
Ugyanígy látni fogjuk a változásokat a Redux
DevTools-ban is. Most a termékeink megjelennek
a state-ben is (nézd meg a 'State' fület),
ha rákattintottál az
products/fetchProducts/fulfilled action-ra.
Ott meg fog jelenni az új státusz is: 'success'.
Kattints most az
products/fetchProducts/pending action-ra és nézd meg,
miben különbözik most a 'State' fül.
Az egyetlen kellemetlen dolog, ami
előfordulhat (erről beszéltem
az előző leckén) - az az adatlekérdezés
megkettőzése. Ennek eredményeképpen a
listánkban nem 8, hanem egész
16 termék lesz és kritikus figyelmeztetések
a fejlesztői konzolon. Foglalkozzunk
ezzel a következő leckén.
Nyisd meg a diákalkalmazásodat.
Nyisd meg benne a studentsSlice.js fájlt. A
createSlice függvény törzsében
a reducers tulajdonság után add hozzá a extraReducers tulajdonságot.
Add át a extraReducers metódusnak a builder objektumot.
A builder.addCase metódus segítségével
adj hozzá kezelést a pending,
fulfilled és rejected action-ökhöz, amelyeket
a fetchStudents küld az adatlekérdezés
során, ahogyan azt a leckében bemutattuk.