Redux-да қўшимча редьюсерлар
Келгила, маҳсулотлар билан ишлайдиган илованимизни очайлик,
ундаги productsSlice.js файлини очинг. Шуни айтиш керакки, сиз
fetchProducts thunk-ни алохида функция сифатида яратганимизни
кузатган бўларсиз? Биз буни createSlice thunk-ларни
аниқлашни қўллаб-қувватламагани сабабли қилдик. Бундай ҳолатда
products слайсининг reducer-и products дан ташқарида
аниқланган экшенларга қандай жавоб беришини талаб қиламиз?
Axзир, айнан бизга fetchProducts thunki жўнатадиган
экшенларни қайта ишлаш керак.
Бундай ҳолатлар учун createSlice да extraReducers
хусусияти мавжуд бўлиб, у қўшимча редьюсерларни
қўшиш имконини беради, улар ўз навбатида мазкур слайсда
эмас, бошқа жойда аниқланган экшенларни қайта ишлайди.
Келгила, энди createSlice функцияси tanasida, барча редьюсерлар
билан reducers хусусиятидан сўнг яна бир extraReducers
усулини қўшайлик:
extraReducers() {},
Биз бу усулга объектни узатишимиз керак
builder, унинг қўшимча редьюсерларни
қўшиш имконини берадиган усуллари мавжуд:
extraReducers(builder) {},
Биз builder нинг усулларидан бири -
addCase дан фойдаланамиз, у биринчи параметр сифатида
action creator-ни, иккинчи параметр сифатида esa 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 та маҳсулот пайдо бўлади
ва ишлаб чиқарувчи консолидаги инобатга олинadigan огоҳлантиришлар.
Келгила, буни кейинги дарсда ҳал қиламиз.
Талабалар билан ишлайдиган илованингизни очинг.
Ундаги studentsSlice.js файлини очинг.
createSlice функцияси tanasida, reducers
хусусиятидан сўнг extraReducers хусусиятини қўшинг.
extraReducers усулига builder ни узатинг.
builder.addCase усули ёрдамида
pending, fulfilled ва rejected экшенларини
қайта ишлашни қўшинг, улар fetchStudents томонидан
маълумотлар сўралганда жўнатилади, дарсда кўрсатилганидек.