დამატებითი რედიუსერები Redux-ში
მოდით გავხსნათ ჩვენი პროდუქტების აპლიკაცია,
და მასში ფაილი productsSlice.js. ალბათ
შეამჩნიეთ, რომ ჩვენ შევქმენით thunk fetchProducts
ცალკე ფუნქციად? ჩვენ ასე გავაკეთეთ, რადგან
createSlice არ უჭერს მხარს thunks-ების განსაზღვრას.
როგორ უნდა გავაძლიეროთ ამ შემთხვევაში
სლაის products რედიუსერი, რომ უპასუხობდეს
ექშენებს, რომლებიც განსაზღვრულია products-ის
გარეთ? ბოლოს და ბოლოს, ჩვენ გვჭირდება
დავამუშავოთ ის ექშენები, რომლებსაც
აგზავნის thunk fetchProducts.
ასეთი შემთხვევებისთვის createSlice-ს
აქვს თვისება extraReducers, რომელიც
საშუალებას აძლევს დაემატოს
დამატებითი რედიუსერები, რომლებიც
თავის მხრივ დაამუშავებენ ექშენებს,
რომლებიც განსაზღვრულია არა ამ კონკრეტულ სლაისში.
მოდით ახლა createSlice ფუნქციის ტანში
reducers თვისების შემდეგ, ყველა რედიუსერთან
ერთად დავამატოთ კიდევ ერთი მეთოდი extraReducers:
extraReducers() {},
ამ მეთოდს ჩვენ უნდა გადავცეთ ობიექტი
builder, რომელსაც აქვს მეთოდები,
რომელთა დახმარებითაც შესაძლებელია დამატებითი
რედიუსერების დამატება:
extraReducers(builder) {},
ჩვენ გამოვიყენებთ ერთ-ერთ მეთოდს builder-იდან -
addCase-ს, რომელიც პირველ პარამეტრად იღებს
action creator-ს, ხოლო მეორედ - reducer-ს. ერთ-ერთი
ექშენი, რომელსაც ჩვენ გამოგვიგზავნის
fetchProducts მოთხოვნის დროს არის
fetchProducts.pending, რაც მიგვანიშნებს,
რომ მოთხოვნა გაიგზავნა. მოდით ამ
შემთხვევაში შევცვალოთ სტატუსი 'in progress'-ზე
(მანამდე ის იყო 'idle'):
extraReducers(builder) {
builder.addCase(fetchProducts.pending, (state) => {
state.status = 'in progress'
})
},
ახლა დავამუშავოთ ექშენი, რომელიც გაიგზავნება
წარმატებული მოთხოვნის შემთხვევაში. აქ ჩვენ
შევცვლით არა მხოლოდ სტეიტის სტატუსს
'success'-ზე, არამედ პროდუქტებს
products სლაისში payload ექშენიდან.
ყველა პროდუქტის შესაგროვებლად დაგვჭირდება
მეთოდი 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)
})
},
წარუმატებელი მოთხოვნის შემთხვევაში ჩვენ შევცვლით
სტატუსს 'fail'-ზე და სტეიტში
ჩავწერთ შეცდომის შეტყობინებას:
.addCase(fetchProducts.rejected, (state, action) => {
state.status = 'fail'
state.error = action.error.message
})
თუ ახლა ჩვენ გავუშვებთ ჩვენს აპლიკაციას
და მენიუში ვიმუშავებთ 'Products'-ზე, მაშინ
რამდენიმე წამში (გახსოვთ დაგვიანება,
რომელიც ჩვენ სერვერზე დავაყენეთ?) ვნახავთ
პროდუქტების სიას.
ასევე ჩვენ ვნახავთ ცვლილებებს Redux
DevTools-ში. ახლა ჩვენი პროდუქტები გამოჩნდება
სტეიტშიც (შეხედეთ ჩანართს 'State'),
თუ თქვენ დააკლიკეთ ექშენს
products/fetchProducts/fulfilled.
იქვე გამოჩნდება ახალი სტატუსი 'success'.
ახლა დააკლიკეთ ექშენს
products/fetchProducts/pending და შეხედეთ,
რით განსხვავდება ახლა ჩანართი 'State'.
ერთადერთი უსიამოვნო მომენტი, რაც
შეიძლება მოგეხდინოთ (მე ვისაუბრე ამაზე
წინა გაკვეთილზე) - ეს არის მონაცემების
მოთხოვნის დუბლირება. შედეგად, ჩვენს
სიაში არ იქნება 8, არამედ მთლიანი
16 პროდუქტი და კრიტიკული გაფრთხილებები
დეველოპერის კონსოლში. მოდით
გავერკვიოთ ამაში შემდეგ გაკვეთილზე.
გახსენით თქვენი აპლიკაცია სტუდენტებთან.
გახსენით მასში ფაილი studentsSlice.js.
createSlice ფუნქციის ტანში reducers
თვისების შემდეგ დაამატეთ თვისება extraReducers.
გადაეცით მეთოდს extraReducers builder.
builder.addCase მეთოდის დახმარებით
დაამატეთ დამუშავება ექშენებისთვის pending,
fulfilled და rejected, რომლებსაც
აგზავნის fetchStudents მონაცემების
მოთხოვნის დროს, როგორც ეს ნაჩვენები იყო გაკვეთილზე.