Zusätzliche Reducer in Redux
Lassen Sie uns unsere Produktanwendung öffnen,
und darin die Datei productsSlice.js. Wahrscheinlich ist Ihnen
aufgefallen, dass wir den Thunk fetchProducts
als separate Funktion erstellt haben? Wir haben das so gemacht,
weil createSlice die Definition von
Thunks nicht unterstützt. Wie können wir in diesem Fall den
Reducer des Slices products dazu bringen, auf Actions zu reagieren,
die außerhalb von products definiert sind?
Schließlich müssen wir genau die Actions verarbeiten,
die vom Thunk fetchProducts gesendet werden.
Für solche Fälle hat createSlice
die Eigenschaft extraReducers, die es erlaubt,
zusätzliche Reducer hinzuzufügen, die
wiederum Actions verarbeiten können,
die nicht in diesem Slice definiert sind.
Lassen Sie uns nun im Körper der Funktion createSlice
nach der Eigenschaft reducers mit allen Reducern
noch eine Methode extraReducers hinzufügen:
extraReducers() {},
Wir müssen dieser Methode ein Objekt
builder übergeben, das Methoden hat, mit
deren Hilfe man
zusätzliche Reducer hinzufügen kann:
extraReducers(builder) {},
Wir werden eine der Methoden von builder verwenden -
addCase, die als ersten Parameter einen
Action Creator und als zweiten einen Reducer entgegennimmt. Eine der
Actions, die uns
fetchProducts bei einer Anfrage sendet, ist
fetchProducts.pending, was uns sagt,
dass die Anfrage gesendet wurde. Lassen Sie uns in diesem
Fall den Status auf 'in progress' ändern
(zuvor war er 'idle'):
extraReducers(builder) {
builder.addCase(fetchProducts.pending, (state) => {
state.status = 'in progress'
})
},
Lassen Sie uns nun die Action verarbeiten, die im
Falle einer erfolgreichen Anfrage gesendet wird. Hier werden wir
nicht nur den Status im State auf
'success' ändern, sondern auch die Produkte im
Slice products aus dem payload der Action übernehmen.
Um alle Produkte zu sammeln, benötigen wir die
Methode 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)
})
},
Im Falle einer fehlgeschlagenen Anfrage ändern wir den
Status auf 'fail' und schreiben in den State
die Fehlermeldung:
.addCase(fetchProducts.rejected, (state, action) => {
state.status = 'fail'
state.error = action.error.message
})
Wenn wir jetzt unsere Anwendung starten
und im Menü auf 'Products' klicken, dann
werden wir nach ein paar Sekunden (erinnern Sie sich an die Verzögerung,
die wir auf dem Server eingestellt haben?) eine
Liste mit Produkten sehen.
Genauso werden wir die Änderungen auch in den Redux
DevTools sehen. Nun erscheinen unsere Produkte auch
im State (schauen Sie auf den Reiter 'State'),
wenn Sie auf die Action
products/fetchProducts/fulfilled geklickt haben.
Dort erscheint auch der neue Status 'success'.
Klicken Sie nun auf die Action
products/fetchProducts/pending und schauen Sie,
wie sich nun der Reiter 'State' unterscheidet.
Der einzige unangenehme Moment, der
Ihnen passieren kann (ich habe in der vorherigen Lektion darüber gesprochen) - ist die Duplizierung
der Datenanfrage. Infolgedessen erhalten wir
in unserer Liste nicht 8, sondern ganze
16 Produkte und kritische Warnungen
in der Entwicklerkonsole. Lassen Sie uns
das in der nächsten Lektion besprechen.
Öffnen Sie Ihre Studentenanwendung.
Öffnen Sie darin die Datei studentsSlice.js. In
dem Körper der Funktion createSlice fügen Sie nach der Eigenschaft
reducers die Eigenschaft extraReducers hinzu.
Übergeben Sie der Methode extraReducers den builder.
Verwenden Sie die Methode builder.addCase,
um die Verarbeitung für die Actions pending,
fulfilled und rejected hinzuzufügen, die
von fetchStudents bei der Datenanfrage
gesendet werden, wie in der Lektion gezeigt.