Các Reducer Bổ Sung trong Redux
Hãy mở ứng dụng sản phẩm của chúng ta,
và trong đó là tệp productsSlice.js. Có lẽ bạn
đã nhận thấy rằng chúng ta đã tạo thunk fetchProducts
như một hàm riêng biệt? Chúng ta làm như vậy bởi vì
createSlice không hỗ trợ định nghĩa
thunks. Vậy làm thế nào chúng ta có thể khiến
reducer của slice products phản hồi các action
được định nghĩa bên ngoài products?
Chẳng phải chúng ta cần xử lý các action
mà thunk fetchProducts gửi đi sao?
Đối với những trường hợp như vậy, createSlice có
thuộc tính extraReducers, cho phép
thêm các reducer bổ sung, và chính
chúng sẽ xử lý các action
được định nghĩa không phải trong slice này.
Bây giờ hãy trong thân hàm createSlice,
sau thuộc tính reducers với tất cả các reducer,
thêm một phương thức nữa extraReducers:
extraReducers() {},
Chúng ta cần truyền cho phương thức này một đối tượng
builder, đối tượng này có các phương thức để
thêm các
reducer bổ sung:
extraReducers(builder) {},
Chúng ta sẽ sử dụng một trong các phương thức của builder -
addCase, phương thức này nhận tham số đầu tiên là
action creator, và tham số thứ hai là reducer. Một trong
các action mà fetchProducts sẽ gửi đi
khi thực hiện yêu cầu là
fetchProducts.pending, cho chúng ta biết
rằng yêu cầu đã được gửi đi. Hãy trong trường hợp này
thay đổi trạng thái thành 'in progress'
(trước đó nó là 'idle'):
extraReducers(builder) {
builder.addCase(fetchProducts.pending, (state) => {
state.status = 'in progress'
})
},
Bây giờ hãy xử lý action sẽ được gửi đi
trong trường hợp yêu cầu thành công. Ở đây chúng ta sẽ
thay đổi không chỉ trạng thái trong state thành
'success', mà còn lấy các sản phẩm vào
slice products từ payload của action.
Để thu thập tất cả sản phẩm chúng ta sẽ cần
phương thức 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)
})
},
Trong trường hợp yêu cầu không thành công, chúng ta sẽ thay đổi
trạng thái thành 'fail' và ghi vào state
thông báo lỗi:
.addCase(fetchProducts.rejected, (state, action) => {
state.status = 'fail'
state.error = action.error.message
})
Nếu bây giờ chúng ta khởi chạy ứng dụng của mình
và trong menu nhấp vào 'Products', thì
sau một vài giây (bạn có nhớ về độ trễ
mà chúng ta đã đặt trên máy chủ không?) chúng ta sẽ thấy
danh sách các sản phẩm.
Tương tự như vậy, chúng ta cũng sẽ thấy các thay đổi trong Redux
DevTools. Bây giờ các sản phẩm của chúng ta sẽ xuất hiện
trong state (hãy xem tab 'State'),
nếu bạn đã nhấp vào action
products/fetchProducts/fulfilled.
Trạng thái mới 'success' cũng sẽ xuất hiện ở đó.
Bây giờ hãy nhấp vào action
products/fetchProducts/pending và xem
tab 'State' bây giờ khác biệt thế nào.
Một điều khó chịu duy nhất có thể
xảy ra với bạn (tôi đã nói về điều này
trong bài học trước) - đó là sự trùng lặp
yêu cầu dữ liệu. Kết quả là, trong
danh sách của chúng ta sẽ không phải là 8, mà là những
16 sản phẩm và các cảnh báo nghiêm trọng
trong bảng điều khiển nhà phát triển. Hãy
giải quyết vấn đề này trong bài học tiếp theo.
Mở ứng dụng về sinh viên của bạn.
Mở trong đó tệp studentsSlice.js. Trong
thân hàm createSlice, sau thuộc tính
reducers, hãy thêm thuộc tính extraReducers.
Truyền cho phương thức extraReducers một builder.
Sử dụng phương thức builder.addCase,
thêm xử lý cho các action pending,
fulfilled và rejected, mà
fetchStudents gửi đi khi yêu cầu
dữ liệu, như được trình bày trong bài học.