Додатни reducer-и у Redux-у
Хајде да отворимо нашу апликацију са производима,
а у њој датотеку productsSlice.js. Вероватно сте
приметили да смо креирали thunk fetchProducts
као посебну функцију? Учинили смо то, јер
createSlice не подржава дефинисање
thunk-ова. Како онда да натерамо
reducer слајса products да реагује на action-е,
који су дефинисани ван products?
Јер нам је управо потребно да обрадимо action-е,
које шаље thunk fetchProducts.
За такве случајеве у createSlice постоји
својство extraReducers, које дозвољава
додавање додатних reducer-а, који
заузврат ће да обрађују action-е,
дефинисане не у овом слајсу.
Хајде сада у телу функције createSlice
после својства reducers са свим reducer-има
да додамо још један метод extraReducers:
extraReducers() {},
Овом методу морамо проследити објекат
builder, који има методе, с
помоћу којих се могу додати
додатни reducer-и:
extraReducers(builder) {},
Користићемо један од метода builder -
addCase, који првим параметром прима
action creator, а другим reducer. Један од
action-а, који ће нам слати
fetchProducts приликом захтева је
fetchProducts.pending, што нам говори
да је захтев послат. Хајде у овом
случају да мењамо статус на 'in progress'
(до тога је био 'idle'):
extraReducers(builder) {
builder.addCase(fetchProducts.pending, (state) => {
state.status = 'in progress'
})
},
Сада да обрадимо action, који ће се послати
у случају успешног захтева. Овде ћемо
мењати не само статус у стању на
'success', већ ћемо и узети производе у
слајс products из payload action-а.
Да бисте сакупили све производе, биће нам потребан
метод 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'),
ако сте кликнули на action
products/fetchProducts/fulfilled.
Тамо ће се појавити и нови статус 'success'.
Кликните сада на action
products/fetchProducts/pending и погледајте,
чиме се сада разликује картица 'State'.
Једини непријатан момент, који
вам се може десити (говорио сам о томе
на претходном часу) - ово је дуплирање
захтева за подацима. Као резултат, у нашем
листи ћемо имати не 8, већ целих
16 производа и критична упозорења
у конзоли програмера. Хајде да
се позабавимо тиме на следећем часу.
Отворите вашу апликацију са студентима.
Отворите у њој датотеку studentsSlice.js. У
телу функције createSlice после својства
reducers додајте својство extraReducers.
Проследите методу extraReducers builder.
Помоћу методе builder.addCase
додајте обраду за action-е pending,
fulfilled и rejected, које
шаље fetchStudents приликом захтева
података, као што је приказано на часу.