Redux'ta Ekstra Reducer'lar
Hadi ürün uygulamamızı açalım,
içindeki productsSlice.js dosyasını açalım. Muhtemelen
fetchProducts thunk'ını ayrı bir fonksiyon olarak
oluşturduğumuzu fark ettiniz? Bunu böyle yaptık,
çünkü createSlice thunk tanımlamayı desteklemiyor.
Peki bu durumda, products slice'ının reducer'ını,
products dışında tanımlanan aksiyonlara nasıl
cevap vermesini sağlarız? Sonuçta fetchProducts
thunk'ının gönderdiği aksiyonları işlememiz gerekiyor.
Bu gibi durumlar için createSlice, başka bir slice'ta
tanımlanmış aksiyonları işleyebilecek
ekstra reducer'lar eklemeye izin veren
extraReducers özelliğine sahiptir.
Şimdi createSlice fonksiyonunun gövdesinde,
tüm reducer'ların bulunduğu reducers özelliğinden
sonra bir extraReducers metodu daha ekleyelim:
extraReducers() {},
Bu metoda, metodları aracılığıyla ekstra reducer'lar
eklenebilen bir builder nesnesi geçmeliyiz:
extraReducers(builder) {},
builder'ın metodlarından biri olan, ilk parametre
olarak bir action creator, ikinci parametre olarak
bir reducer alan addCase metodunu kullanacağız.
fetchProducts thunk'ının istek sırasında
göndereceği aksiyonlardan biri, bize isteğin
gönderildiğini söyleyen fetchProducts.pending'dir.
Bu durumda durumu 'in progress' olarak
değiştirelim (öncesinde 'idle' idi):
extraReducers(builder) {
builder.addCase(fetchProducts.pending, (state) => {
state.status = 'in progress'
})
},
Şimdi başarılı bir istek durumunda gönderilecek
aksiyonu işleyelim. Burada durumu 'success'
olarak değiştirmekle kalmayacağız, aynı zamanda
ürünleri, aksiyonun payload'ından alıp
products slice'ına kaydedeceğiz. Tüm ürünleri
toplanmak için concat metoduna ihtiyacımız olacak:
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)
})
},
Başarısız bir istek durumunda durumu
'fail' olarak değiştireceğiz ve state'e
hata mesajını yazacağız:
.addCase(fetchProducts.rejected, (state, action) => {
state.status = 'fail'
state.error = action.error.message
})
Eğer şimdi uygulamamızı başlatıp menüden
'Products''a tıklarsak, birkaç saniye
sonra (sunucuda ayarladığımız gecikmeyi
hatırlıyor musunuz?) bir ürün listesi göreceğiz.
Aynı şekilde Redux DevTools'ta da değişiklikleri
göreceğiz. Artık ürünlerimiz state'te de görünecek
(eğer products/fetchProducts/fulfilled aksiyonuna
tıkladıysanız 'State' sekmesine bakın). Orada
yeni bir 'success' durumu da görünecek. Şimdi
products/fetchProducts/pending aksiyonuna tıklayın
ve 'State' sekmesinin nasıl değiştiğine bakın.
Başınıza gelebilecek tek tatsız durum (bunu bir
önceki derste söylemiştim) - veri isteğinin
yinelenmesidir. Sonuç olarak, listemizde
8 yerine tam 16 ürün olacak ve geliştirici
konsolunda kritik uyarılar alacağız. Hadi bu
konuyu bir sonraki derste ele alalım.
Öğrenci uygulamanızı açın. İçindeki
studentsSlice.js dosyasını açın.
createSlice fonksiyonunun gövdesinde,
reducers özelliğinden sonra
extraReducers özelliğini ekleyin.
extraReducers metoduna bir builder geçin.
builder.addCase metodunu kullanarak,
derste gösterildiği gibi, veri isteği sırasında
fetchStudents tarafından gönderilen
pending, fulfilled ve
rejected aksiyonlarının işlenmesini ekleyin.