Yderligere Reducere i Redux
Lad os åbne vores produktapplikation,
og i den filen productsSlice.js. Du har sikkert
lagt mærke til, at vi oprettede thunken fetchProducts
som en separat funktion? Vi gjorde det sådan, fordi
createSlice ikke understøtter definition af
thunks. Hvordan får vi i så fald reduceren
i products-sliceset til at reagere på actions,
der er defineret uden for products-sliceset?
Det er netop det, vi har brug for, for at håndtere de actions,
som thunken fetchProducts sender.
For sådanne tilfælde har createSlice
egenskaben extraReducers, som tillader
os at tilføje yderligere reducere, som
til gengæld vil håndtere de actions, der
er defineret uden for dette slices.
Lad os nu i kroppen af funktionen createSlice
efter egenskaben reducers med alle reducerne
tilføje endnu en metode extraReducers:
extraReducers() {},
Vi skal overgive et objekt til denne metode
builder, som har metoder, der
kan bruges til at tilføje
yderligere reducere:
extraReducers(builder) {},
Vi vil bruge en af builder-metoderne -
addCase, som tager en action creator som første
parameter og en reducer som anden parameter. En af
de actions, som fetchProducts vil sende
når der anmodes, er
fetchProducts.pending, som fortæller os
at anmodningen er sendt. Lad os i dette
tilfælde ændre status til 'in progress'
(før var den 'idle'):
extraReducers(builder) {
builder.addCase(fetchProducts.pending, (state) => {
state.status = 'in progress'
})
},
Lad os nu håndtere den action, som sendes
ved en vellykket anmodning. Her vil vi
ændre ikke kun status i staten til
'success', men også hente produkterne i
products-sliceset fra actionens payload.
For at samle alle produkter har vi brug for
metoden concat:
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)
})
},
Ved en mislykket anmodning vil vi ændre
status til 'fail' og skrive fejlmeddelelsen
i staten:
.addCase(fetchProducts.rejected, (state, action) => {
state.status = 'fail'
state.error = action.error.message
})
Hvis vi starter vores applikation nu
og klikker på 'Products' i menuen, vil
vi om et par sekunder (husk forsinkelsen,
som vi satte på serveren?) se en
liste med produkter.
På samme måde vil vi se ændringerne i Redux
DevTools. Nu vil vores produkter dukke op i
statens (se fanen 'State'),
hvis du klikkede på actionen
products/fetchProducts/fulfilled.
Den nye status 'success' vil også dukke op der.
Klik nu på actionen
products/fetchProducts/pending og se,
hvordan fanen 'State' er anderledes nu.
Det eneste ubehagelige øjeblik, som
muligvis er sket for dig (jeg talte om det
i den forrige lektion) - er duplikering af
dataanmodningen. Som et resultat heraf får vi
ikke 8, men hele 16 produkter i listen og kritiske advarsler
i udviklerkonsollen. Lad os
finde ud af dette i næste lektion.
Åbn din studerendeapplikation.
Åbn filen studentsSlice.js i den. I
kroppen af funktionen createSlice tilføj egenskaben extraReducers efter egenskaben
reducers.
Overgiv builder til metoden extraReducers.
Brug metoden builder.addCase
til at tilføje håndtering for actionerne pending,
fulfilled og rejected, som
fetchStudents sender under dataanmodningen,
som vist i lektionen.